CXX.DIFF.WIDTH.STR_AND_FUNC

相互に置き換え可能な方法で関数で使用されるナロー文字列とワイド文字列。

CXX.DIFF.WIDTH.STR_AND_FUNC チェッカーは、ナロー文字列引数がワイド文字列関数に渡されるインスタンス、またはワイド文字列引数がナロー文字列関数に渡されるインスタンスを検出します。

脆弱性とリスク

ワイド文字とナロー文字はサイズが異なるため、スケーリング問題のリスクがあります。また、文字列によっては長さを決定することで問題が発生することがあります。これは、ワイド文字列は null ワイド文字で終了し、null バイトを含む可能性があるためです。

軽減と防止

この問題を回避するには、適切な幅の関数を使用し、関数の呼び出し時にナロー文字列とワイド文字列を修正します。

脆弱コード例 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;
  }

この修正例では、ワイド文字列のコピーを含めるために必要なバイト数 (null 終端ワイド文字を含む) が正しく計算されます。