JPCERT コーディネーションセンター

安全・安心なIT社会のための、国内・国際連携を支援する

お問い合わせ サイトマップ English

Home > ラーニング > セキュアコーディング > C セキュアコーディングスタンダード > 01. プリプロセッサ (PRE)

  1. HTTPS

01. プリプロセッサ (PRE)

最終更新: 2010-07-26

PRE07-C. "??" の繰り返しは避ける

"?" 二つは3文字表記の始まりを表す。C99 [ISO/IEC 9899:1999] によれば:

次に示す文字の並び[3文字表記(trigraph sequence)という。]がソースファイルの中にある場合、その三つの文字の並びを対応する一文字に置き換える。

??= #   ??) ]   ??! |
??( [   ??' ^   ??> }
??/ \   ??< {   ??- ~
違反コード

このコード例では、a++ が実行されない。なぜなら、3文字表記 ??/\ に置き換えられ、a++ がコメント行と同一行に配置されてしまうからである。

// a の値はなんだろう??/
a++;
適合コード

以下のコード例は、"?" の間に空白文字をひとつ入れることにより、予期せず3文字表記にならないようにしている。

// a の値はなんだろう? ?/
a++;
違反コード

このコード例は3文字表記 ??! を含む。これは | に置き換えられる。

size_t i = /* 初期値 */;
if (i > 9000) {
  if (puts("Over 9000!??!") == EOF) {
     /* エラー処理 */
   }
}

C99 に適合したコンパイラを使うと、このコードの出力は Over 9000!| になる。

適合コード

以下のコード例は文字列連結を用いて二つの "?" を連結している。このようにしなければ、3文字表記の始まりと解釈されてしまう。

size_t i = /* 初期値 */;
/* i への代入 */
if (i > 9000) {
   if (puts("Over 9000!?""?!") == EOF) {
     /* エラー処理 */
   }
}

上記のコードは意図したとおり Over 9000!??! を出力する。

リスク評価

うっかり3文字表記をしてしまうと予期せぬ動作を引き起こすおそれがある。コンパイラによっては、3文字表記がある場合に警告を出すオプションや3文字表記を無効にするオプションを提供している。警告を出すオプションを使用し、コンパイル時に警告が出ないようなコードにせよ。(「MSC00-C. 高い警告レベルで警告を出さずにコンパイルする」を参照)

レコメンデーション 深刻度 可能性 修正コスト 優先度 レベル
PRE07-C P2 L3
自動検出

LDRA tool suite V 7.6.0 はこのレコメンデーションの違反を検出できる。

GCC コンパイラは -Wtrigraphs フラグを使用することでこのレコメンデーションの違反を検出できる。

参考情報
  • [ISO/IEC 9899:1999] Section 5.2.1.1, "Trigraph sequences"
  • [MISRA 04] Rule 4.2
翻訳元

PRE07-C. Avoid using repeated question marks

Top へ