ARR34-C. 式中の配列の型は適合していることを保証する
C 言語規格 [ISO/IEC 9899:2011]のセクション 6.7.6.2 によると、1 つの式の中で 2 つ以上の適合していない(incompatible)配列を使用すると、未定義の動作となる。附属書 J [ISO/IEC 9899:2011] 「未定義の動作」の 76 も参照すること。
2つの配列型が適合する(compatible)には、両者が適合する要素型を持ち、かつ、両者のサイズ指定子が同じ定数値である必要がある。これらの性質のいずれかに違反すると、未定義の動作となる。
違反コード
下記の違反コード例では、2つの配列 a
と b
は、配列が適合するために必要な、サイズ指定子が等しいという条件を満たしていない。a
と b
が等しくないため、a
の有効であるはずのメンバへの書込みが、定義されたメモリ境界を超え、任意のメモリ上書きにつながる可能性がある。
enum { ROWS = 10, COLS = 15 }; void func(void) { int a[ROWS][COLS]; int (*b)[ROWS] = a; }
多くのコンパイラは、1つの式中で使用される2つの配列型が適合していなければ警告を出す。
適合コード
下記の適合コードにおいて、b
は a
と同じ要素数を持つ配列を指すように宣言されており、配列が適合するために必要なサイズ指定子が等しい条件を満たしている。
enum { ROWS = 10, COLS = 15 }; void func(void) { int a[ROWS][COLS]; int (*b)[COLS] = a; }
処理系固有の詳細
GCC 4.8.1 および Microsoft Visual Studio 2013 はいずれも、1 つの式で使用される 2 つの配列型が適合していないときに警告を出す。
リスク評価
適合していない配列型を使用すると、境界外のメモリが参照されたり任意のコードが実行される可能性がある。
ルール |
深刻度 |
可能性 |
修正コスト |
優先度 |
レベル |
---|---|---|---|---|---|
ARR34-C |
高 |
低 |
中 |
P6 |
L2 |
自動検出
ツール |
バージョン |
チェッカー |
説明 |
---|---|---|---|
|
|
可変長配列を使用していなければ、このルールの違反を検出できる。 |
|
PRQA QA-C | 8.1 |
0563 (C) |
実装済み |
関連するガイドライン
MITRE CWE | CWE-119, Failure to constrain operations within the bounds of an allocated memory buffer |
参考文献
[ISO/IEC 9899:2011] | Subclause 6.7.6.2, "Array Declarators" |
翻訳元
これは以下のページを翻訳したものです。
ARR34-C. Ensure that array types in expressions are compatible (revision 66)