...
| Code Block |
|---|
|
#include <stddef.h>
#include <string.h>
void func(void) {
wchar_t wide_str1[] = L"0123456789";
wchar_t wide_str2[] = L"0000000000";
strncpy(wide_str2, wide_str1, 10);
} |
Noncompliant Code Example (Using wcsncpy instead of strncpy)
...
| Code Block |
|---|
|
#include <wchar_t>
void func(void) {
char narrow_str1[] = "0123456789";
char narrow_str2[] = "0000000000";
wcsncpy(narrow_str2, narrow_str1, 10);
} |
Implementation Details
The C Standard recognizes wchar_t[] and char[] as distinct types. As a result, many compilers will yield a warning if the inappropriate function is used. For example, the following warnings were generated when the second noncompliant example was compiled with no flags in GCC on a Linux i686 platform:
...
| Code Block |
|---|
|
#include <stddef.h>
#include <string.h>
#include <wchar.h>
void func(void) {
wchar_t wide_str1[] = L"0123456789";
wchar_t wide_str2[] = L"0000000000";
wcsncpy(wide_str2, wide_str1, 10); /* Use of proper-width function. */
wcsncpy(wide_str2, wide_str1, 10);
char narrow_str1[] = "0123456789";
char narrow_str2[] = "0000000000";
strncpy(narrow_str2, narrow_str1, 10); /* Use of proper-width function. */
strncpy(narrow_str2, narrow_str1, 10);
} |
Noncompliant Code Example (strlen())
...
| Code Block |
|---|
|
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
void func(void) {
wchar_t wide_str1[] = L"0123456789";
wchar_t *wide_str2 = (wchar_t *)malloc(strlen(wide_str1) + 1);
if (wide_str2 == NULL) {
/* Handle error */
}
/*
... */
free(wide_str2);
wide_str2 = NULL;
} |
The strlen() function counts the number of characters in a null-terminated byte string preceding the terminating null byte. However, wide characters contain null bytes, particularly when taken from the ASCII character set, as in this example. As a result, the strlen() function will return the number of bytes preceding the first null byte in the string.
...
| Code Block |
|---|
|
#include <stddef.h>
#include <stdlib.h>
#include <wchar.h>
void func(void) {
wchar_t wide_str1[] = L"0123456789";
wchar_t *wide_str2 = (wchar_t *)malloc(
(wcslen(wide_str1) + 1) * sizeof(wchar_t)
);
if (wide_str2 == NULL) {
/* Handle error */
}
/* ... */
free(wide_str2);
wide_str2 = NULL;
} |
Risk Assessment
Failure to use the proper-width string functions can lead to buffer overflows and the execution of arbitrary code by an attacker.
...