Home > ラーニング > セキュアコーディング > C セキュアコーディングスタンダード > 01. プリプロセッサ (PRE)
インクルードされたヘッダファイル名が確実に一意となるよう配慮しなければならない。C99 [ISO/IEC 9899:1999] によると、
処理系は,一つ以上の英字又は数字(5.2.1 で定義する)の列の後ろにピリオド(.)及び一つの英字が続く形式に対して,一意の対応付けを提供しなければならない。最初の文字は,英字でなければならない。処理系は,アルファベットの大文字と小文字の区別を無視してもよく,対応付けはピリオドの前8文字に対してだけ有効であると限定してもよい
これはつまり以下を意味する
ヘッダファイル名が一意であることを保証するには、インクルードされるすべてのファイル名が、その最初の8文字あるいは(1文字の)ファイル拡張子において異なっていなくてはならない。(大文字小文字の区別が無効なかたちで)
このレコメンデーションに適合するということは、必ずしも短いファイル名を使用することを求めているわけではなく、ファイル名が一意であることを求めているだけであることに注意。
以下のコードにはヘッダファイルへのリファレンスが含まれている。これらのヘッダファイルは、様々な環境において別のファイルとして存在しうるのかもしれないが、C99に準拠したコンパイラはこれらを同一のファイルとして解釈するかもしれない。
#include "Library.h" #include <stdio.h> #include <stdlib.h> #include "library.h" #include "utilities_math.h" #include "utilities_physics.h" #include "my_library.h" /* プログラムの残りの部分 */
Library.h および library.h は同一のファイルを参照しているかもしれない。また、最初の8文字だけしか有効であると保証されていないため、utilities_math.h と utilities_physics.h が別のファイルとして解釈されるかどうかは不明である。さらに、my_libraryOLD.h というようなファイルが存在すると、my_library.h の代わりにインクルードされてしまうかもしれない。
以下の解決法では、関連するファイルのファイル名を変更し、上述の条件においてファイル名が一意になるようにすることで、あいまいさを回避している。
#include "Lib_main.h" #include <stdio.h> #include <stdlib.h> #include "lib_2.h" #include "util_math.h" #include "util_physics.h" #include "my_library.h" /* プログラムの残りの部分 */
my_libraryOLD.h のようなファイル名のあいまいさを緩和する唯一の解決策は、(最初の8文字で元のファイル名と区別できるように)古いファイル名に接頭辞をつけるか、拡張子を追加することである(たとえば my_library.h.old)。
PRE08-EX1: C99 はファイル名の先頭8文字だけが有効であることを要求しているが、今日の多くのシステムは長いファイル名を扱うことができ、これらのシステム上の典型的なコンパイラは長いファイル名を区別することができる。したがって、コードが移植される先のすべての処理系がこのような長いファイル名を区別できるのであれば、ヘッダファイルに長いファイル名を使ってもよい。
ヘッダファイルの一意性を保証できないと、(たとえば)古いバージョンのヘッダファイルがインクルードされ、それにより間違ったマクロ定義や使わなくなった関数プロトタイプがインクルードされてしまったり、コンパイラが検出できたりできなかったりするエラーを引き起こす結果となる恐れがある。また、一意であることが保証されない長いファイル名を使うことで、移植性が問題になるかもしれない。
| レコメンデーション | 深刻度 | 可能性 | 修正コスト | 優先度 | レベル |
|---|---|---|---|---|---|
| PRE08-C | 低 | 低 | 中 | P2 | L3 |
Klocwork Version 8.0.4.16 は IF_DUPL_HEADER チェッカを使ってこのレコメンデーションの違反を検出することができる。