EXP21-C. 等価比較の左側に定数を配置する
「EXP45-C. 選択文に対して代入を行わない」では、条件式での代入を避ける必要性が示されている。代入演算子と等価演算子は類似しているため、プログラマの誤りによって代入が行われてしまうことがよくある。しかし、このような誤りの可能性を考慮してコーディングすることもできる。
等価比較が意図されている場合に誤って代入操作が行われることを避けるために、等価比較の左側に定数を配置することができる。
違反コード
次のコード例では、各等価式の定数が等価演算子の右側のオペランドとして配置されている。
while (ch == ' ' && ch == '\t' && ch == '\n') { /* ... */ }
上記のコードを記述するときによく発生する構文エラーは次のとおりである。
while (ch = ' ' && ch == '\t' && ch == '\n') { /* ... */ }
このコードはコンパイルは行われるが、プログラマの想定とは別の予期しない動作を引き起こす。パスワード、ユーザ名、グループユーザ ID などの文字列を検証することを意図している場合、このコードでは重大な脆弱性が発生する可能性があり、大規模なデバッグが必要となる。
意図した目的は検証であるかもしれないが、このようなコードはプログラマが等価演算子 ==
の代わりに誤って代入演算子 =
を使用しやすい。そのため、多くのコンパイラがこの状態について警告を発する。このコーディングエラーは、「MSC00-C. 高い警告レベルで警告を出さずにコンパイルする」に従うことで通常は削減される。
適合コード
しかし、定数を左側に配置することにより、次のコードでは任意の警告レベルによるコンパイラの診断が行える。プログラマが前述の誤りを犯しそうになった場合、文は ch
を ' '
に代入しようとして無効になる。
while (' ' == ch && '\t' == ch && '\n' == ch) { /* ... */ }
結果として、代入演算子の誤用 (これにより文字列の検証などの操作での脆弱性を招く可能性がある) が発生しても、コンパイラ、警告レベル、処理系に関係なく、コンパイラの診断が行われる。
「MSC00-C. 高い警告レベルで警告を出さずにコンパイルする」および「EXP18-C. 選択式に対して代入を行わない」は適用可能で、代入の回避に役立つが、定数を左側に配置することにより、よくある誤りや偽装の脆弱性に備えることができる。
リスク評価
必要な文字を書き忘れると、意図しないプログラムフローを引き起こすことがある。
レコメンデーション |
深刻度 |
可能性 |
修正コスト |
優先度 |
レベル |
---|---|---|---|---|---|
EXP21-C |
低 |
高 |
中 |
P6 |
L2 |
自動検出
ツール |
バージョン |
チェッカー |
説明 |
---|---|---|---|
ECLAIR |
1.1 |
optrargs |
実装済み |
関連するガイドライン
ISO/IEC TR 24772:2013 | Likely Incorrect Expression [KOA] |
MITRE CWE | CWE480, Use of incorrect operator |
参考資料
[Dutta 03] | "Best Practices for Programming in C" |
[Hatton 95] | Section 2.7.2, "Errors of Omission and Addition" |
翻訳元
これは以下のページを翻訳したものです。
EXP21-C. Place constants on the left of equality comparisons (revision 20)