Home > ラーニング > セキュアコーディング > C セキュアコーディングスタンダード > 02. 宣言と初期化 (DCL)
あるスコープが他方のスコープに包含されるような二つのスコープで同一の変数名を使用しないこと。たとえば、
変数名を再利用すると、どの変数が変更されているのだろうという混乱をプログラマに与える。また、変数名が再利用されているというのは、変数名が一般的に過ぎるということでもある。
以下のコード例では、翻訳単位のはじまりで msg 識別子を定義し(ファイル有効範囲)、同じ識別子を使ってreport_error()関数にローカルな文字配列を宣言している。したがって、プログラマは意図せず、report_error()関数にローカルに宣言されたmsg配列へ文字列をコピーし、グローバル変数の msg を初期化し損ね、バッファオーバーフローを引き起こす可能性がある。
char msg[100];
void report_error(char *error_msg) {
char msg[80];
/* ... */
strncpy(msg, error_msg, sizeof(msg));
return;
}
int main(void) {
char error_msg[80];
/* ... */
report_error(error_msg);
/* ... */
}
以下の解決法では、より説明的な違う名前を使っている。
char system_msg[100];
void report_error(char *error_msg) {
char default_msg[80];
/* ... */
if (error_msg)
strncpy(system_msg, error_msg, sizeof(system_msg));
else
strncpy(system_msg, default_msg, sizeof(system_msg));
system_msg[ sizeof(system_msg) - 1] = '\0';
return;
}
int main(void) {
char error_msg[80];
/* ... */
report_error(error_msg);
/* ... */
}
ブロックが小さい場合、変数宣言がすぐに目に見えるため、変数名を再利用する危険性は緩和される。しかし、上記の例であっても、変数名を再利用することは望ましくない。
グローバルにもローカルにも異なる変数名を使用することで、コンパイラは、ディベロッパーが変数名に関してより厳密かつ説明的であることを強制する。
サブスコープで変数名を再利用すると、間違った変数を意図せず参照することにつながりうる。
| レコメンデーション | 深刻度 | 可能性 | 修正コスト | 優先度 | レベル |
|---|---|---|---|---|---|
| DCL01-C | 低 | 低 | 中 | P2 | L3 |
LDRA tool suite Version 7.6.0 はこのレコメンデーションの違反を検出することができる。
Splint Version 3.1.1 はこのレコメンデーションの違反を検出することができる。
Compass/ROSE はこのレコメンデーションの違反を検出することができる。
Klocwork Version 8.0.4.16 は IF_MULTI_DECL, IF_MULTI_DEF, IF_MULTI_KIND チェッカを使ってこのレコメンデーションの違反を検出することができる。