CXX.DIFF.WIDTH.STR_AND_FUNC

窄和宽字符串在函数中可互换使用。

CXX.DIFF.WIDTH.STR_AND_FUNC 检查器会查找将窄字符串参数传递给宽字符串函数或者将宽字符串参数传递给窄字符串函数的示例。

漏洞与风险

存在发生缩放问题的风险,因为宽字符和窄字符的大小不同。此外,在确定某些字符串的长度时也会出现问题,因为宽字符串由空宽字符确定,可能包含空字节。

缓解与预防

为避免此问题,在调用函数时请使用适当的宽度函数以及正确的窄和宽字符串。

漏洞代码示例 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
  }

在此示例中,Klocwork 在第 8 行报告了与 strncpy() 函数相关的缺陷,指出将宽字符串传递给预期获得窄字符串的函数。

修正代码示例 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
   }

此修正代码示例使用适当的宽度函数 wcsncpy() 来复制宽字符串,可确保数据不会截断。

漏洞代码示例 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;
  }

在此示例中,Klocwork 报告了与代码相关的缺陷,该代码使用 strlen() 函数来确定宽字符串的大小。

修正代码示例 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;
  }

此修正代码示例正确地计算包含宽字符串的副本所需的字节数,包括结尾的空宽字符。