INT07-C. 数値には符号の有無を明示した char 型のみを使用する
3つの型 char
、signed char
、および unsigned char
を総称して文字型(character type)と呼ぶ。処理系は、char
を、signed char
または unsigned char
のいずれかと同じ値の範囲、同じ表現形式、そして同じ動作をするものとして定義しなければならない。char
はどちらに定義されたとしても、signed char
とも unsigned char
とも異なる型であり、それらと互換性はない。
文字型変数に数値を格納し、使用するには、signed char
もしくは unsigned char
型のみを使うこと。この方法が唯一型の符号を保証できる手段である。文字の表現に関する詳細は、「STR00-C. 文字の表現には適切な型を使用する」を参照のこと。
違反コード
以下のコード例では、char
型の変数 c
は符号付きかもしれないし、符号無しかもしれない。文字型が8ビットの2の補数表現であると仮定すると、このコードは i/c = 5
(符号無し) あるいは i/c = -17
(符号付き) のいずれかを出力する。これらの整数が符号付きであるか符号無しであるかを知らずして、プログラムの正しさを判断することは難しい。
char c = 200;
int i = 1000;
printf("i/c = %d\n", i/c);
適合コード
以下の適合コードでは、変数 c
を unsigned char
として宣言している。つづく除算演算は char
の符号に左右されることなく、予測可能な結果になる。
unsigned char c = 200;
int i = 1000;
printf("i/c = %d\n", i/c);
例外
INT07-EX1: 「FIO34-C. 文字入出力関数の返り値の取得には int 型を使用する」は int
型の返り値を返す文字入出力関数について言及している。これらの関数は返り値を算術型で返すが、値は本質的には数値ではないため、その値を後で char
型変数に格納してもよい。
リスク評価
コード上はごく小さなエラーだが、きわめて幅広い範囲の深刻な脆弱性を招く可能性がある。最低でも、このエラーが原因で異なるプラットフォームで予期せぬ数値になる可能性がある。予期せぬ整数値が配列やポインタに利用されると、バッファオーバーフローや無効なメモリアクセスを引き起こすおそれがある。
レコメンデーション |
深刻度 |
可能性 |
修正コスト |
優先度 |
レベル |
---|---|---|---|---|---|
INT07-C |
中 |
中 |
中 |
P8 |
L2 |
自動検出(最新の情報はこちら)
ツール |
バージョン |
チェッカー |
説明 |
---|---|---|---|
|
|
このレコメンデーションの違反を検出できる。特に、( |
|
ECLAIR |
1.1 |
idb_charplan |
実装済み |
5.0 |
|
CERT C Rule Packを使ってこのレコメンデーションの違反を検出できる |
|
LDRA tool suite |
V. 8.5.4 |
93 S |
実装済み |
V. 3.1.1 |
|
|
|
PRQA QA-C | 8.1 |
3711 |
部分的に実装済み |
関連するガイドライン
CERT C++ Coding Standard | INT07-CPP. Use only explicitly signed or unsigned char type for numeric values |
ISO/IEC TR 24772:2013 | Bit Representations [STR] |
MISRA C:2012 | Rule 10.1 (required) Rule 10.3 (required) Rule 10.4 (required) |
MITRE CWE | CWE-682, Incorrect calculation |
翻訳元
これは以下のページを翻訳したものです。
INT07-C. Use only explicitly signed or unsigned char type for numeric values (revision 73)