SV.FMT_STR.SCAN_IMPROP_LENGTH

互換性のないスキャン長さ修飾子

特定のタイプの書式指定では、h、l、L などのパラメーターの長さ修飾子を書式文字列で使用できます。SV.FMT_STR.PRINT_IMPROP_LENGTH チェッカーは、長さ修飾子を指定の書式指定子とともに使用できない場合に警告を生成します。たとえば、指定 %hf では、長さ修飾子 h を %f 書式指定子とともに使用しても意味がありません。

脆弱性とリスク

通常、コンパイラは、互換性のない長さ修飾子を無視します。ただし、そのような使用事例は、ディベロッパーが別の書式指定を使おうとしたが間違えたため、Klocwork の警告によって設計者が正しい指定の変更を検討してしまうことを示す場合があります。

軽減と防止

パラメーターと長さ修飾子の互換性は、使用している特定のコンパイラによって異なるため、適切な fscanf Linux man pages や MSDN Web サイトなどのコンパイラ別ヘルプまたはドキュメンテーションを確認するのが最適です。一般的なリソースドキュメントは CERT サイトの記事、FIO00-C: 書式文字列の作成における注意点

脆弱コード例

コピー
 void foo(FILE* f, char* pc, int i, long l, struct SomeStruct ss, long double ld) {
     fscanf(f, "%2hs", pc);     // improper use of 'h' modifier
     fscanf(f, "%lc", &i);         
     fscanf(f, "%10ld", &l);
     fscanf(f, "%hx", &i);
     fscanf(f, "%hc", pc);      // 'h' modifier used with 'c' type character
     fscanf(f, "%Lx", &l);      // 'L' modifier used with 'x' type character
     fscanf(f, "%Lf", &ld);    
 }

Klocwork は、書式文字列仕様とパラメーターの間の不一致を示す 2、6、7 行目にエラーのフラグを立てます。書式指定が示すように、2 行目では文字列が期待され、6 行目では文字が期待され、7 行目では 16 進数が期待され、また、これらの行の修飾子で指定に合うものはありません。その一方で、3、4、5 行目は、互換性のある指定と修飾子の例を示しています。

修正コード例

コピー
 void foo(FILE* f, char* pc, int i, long l, struct SomeStruct ss, long double ld) {
     fscanf(f, "%s", pc);
     fscanf(f, "%lc", &i);         
     fscanf(f, "%10ld", &l);
     fscanf(f, "%hx", &i);
     fscanf(f, "%c", pc);
     fscanf(f, "%x", &l);
     fscanf(f, "%Lf", &ld);    
 }

修正されたコードでは、それぞれの書式文字列指定とパラメーターは互換性があります。