EN JP CN

PORTING.UNSIGNEDCHAR.OVERFLOW.FALSE

PORTING.UNSIGNEDCHAR.OVERFLOW.FALSE

関係式が常に false になる場合があります

PORTING チェッカーは、異なるコンパイラ内で特定の実装詳細に依存する可能性があるコードを識別します。PORTING.UNSIGNEDCHAR.OVERFLOW.FALSE チェッカーは、'char' 型の符号によって、関係式が必ず false になる可能性のある状況を検出します。

脆弱性とリスク

'char' データ型は C 標準規格では正確に定義されていないため、インスタンスが符号ありと見なされたり、見なされなかったりする場合があります。コンパイラによっては、コンパイラオプションを使用して 'char' の符号を切り替えることができます。ただし、開発者にとり、コードの移植時に問題が発生しないように常に明確なコードを記述することがベストプラクティスです。

軽減と防止

必ず、'char' 型に符号を付けるかどうかを指定してください。常に厳密に使用される typedef または #define を使用して定義することをお勧めします。

脆弱コード例

1   int has_utf8_byte_order_mark(char *s) {
2     return s[0] == 0xEF && s[1] == 0xBB && s[2] == 0xBF;  /* PORTING.UNSIGNEDCHAR.OVERFLOW.FALSE */
3   }

4   int main() {
5     char *s = "\xEF\xBB\xBFHello, World!\n";
6     if (has_utf8_byte_order_mark(s)) {
7       printf("unicode\n");
8     } else {
9       printf("not unicode\n");
10    }
11    return 0;
12  }

このコード例では、char 型が符号なしの場合にのみ、UTF-8 バイトオーダーマークが検出されます。

修正コード例 1

1   int has_utf8_byte_order_mark(char *s) {
2     return s[0] == '\xEF' && s[1] == '\xBB' && s[2] == '\xBF';
3   }

4   int main() {
5     char *s = "\xEF\xBB\xBFHello, World!\n";
6     if (has_utf8_byte_order_mark(s)) {
7       printf("unicode\n");
8     } else {
9       printf("not unicode\n");
10    }
11    return 0;
12  }

この例の修正コードでは、整数リテラルではなく文字リテラルを使用して比較します。

修正コード例 2

1   int has_utf8_byte_order_mark(unsigned char *s) {
2     return s[0] == 0xEF && s[1] == 0xBB && s[2] == 0xBF;  
3   }

4   int main() {
5     char *s = "\xEF\xBB\xBFHello, World!\n";
6     if (has_utf8_byte_order_mark(s)) {
7       printf("unicode\n");
8     } else {
9       printf("not unicode\n");
10    }
11    return 0;
12  }

このアプローチでは、char ではなく、unsigned char を使用します。

外部参考資料