CXX.DIFF.WIDTH.STR_AND_FUNC
Narrow and wide character strings used interchangeably in functions.
The CXX.DIFF.WIDTH.STR_AND_FUNC checker finds instances in which a narrow string argument is passed to a wide string function or where a wide string argument is passed to a narrow string function.
Vulnerability and risk
There is a risk of scaling problems because wide and narrow characters are different in size. Also, determining the length of some strings is problematic because wide strings are terminated by a null wide character and can contain null bytes.
Mitigation and prevention
To avoid this issue, use proper width functions and correct narrow and wide character strings when calling functions.
Vulnerable code example 1
#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); //Non-compliant code
}
In this example, Klocwork reports a defect on line 8 in reference to the strncpy() function where a wide character string is passed to a function that is expecting a narrow character string.
Fixed code example 1
#include <string.h>
#include <wchar.h>
void func(void) {
wchar_t wide_str1[] = L"0123456789";
wchar_t wide_str2[] = L"0000000000";
/* Use of proper-width function */
wcsncpy(wide_str2, wide_str1, 10); /Compliant code
}
This fixed example uses the proper-width function, wcsncpy(), for copying wide character strings, which ensures that data is not truncated.
Vulnerable code example 2
#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); //Non-compliant
if (wide_str2 == NULL) {
/* Handle error */
}
/* ... */
free(wide_str2);
wide_str2 = NULL;
}
In this example, Klocwork reports a defect in reference to the code using the strlen() function to determine the size of a wide character string.
Fixed code example 2
#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;
}
This fixed example correctly calculates the number of bytes required to contain a copy of the wide string, including the terminating null wide character.