CWARN.NOEFFECT.OUTOFRANGE
範囲外の値
範囲外のリテラル定数による無効なバイナリ比較。
Note: CWARN.NOEFFECT.OUTOFRANGE チェッカーはバイナリ演算子の左または右側の操作結果が署名された 64 ビット変数の幅に合う状況に限られています。
脆弱性とリスク
一方に式が存在し、もう一方にリテラル式が存在するバイナリ比較で、リテラル式の値が式の許容値の範囲外の場合は、比較が無効になります。この種類の比較は、コンテキストに応じて、常に true か、常に false になります。コード内のこのような問題を防止するには、適切に式をキャストするか、この場合は右側のリテラル式を使用する必要があります。
脆弱コード例 1
void foo(){
unsigned char i;
int a[256];
for(i=0;i<256;i++) {
a[i]=1;
}
}
上記の例では、変数 'I' は 255 以上の値を保持できないにもかかわらず、定数 256 と比較されるため、比較 "i<256" は普遍的に true になります。これは無限ループの原因になります。Klocwork は 4 行目で CWARN.NOEFFECT.OUTOFRANGE を生成し、デベロッパーに問題についてアラートを発します。
修正コード例 1
void foo(){
int i;
int a[256];
for(i=0;i<256;i++) {
a[i]=1;
}
}
上記の例で、"unsigned char" の代わりに "int" として変数を宣言する単純な修正が示されたら、変数 'I' の値の許容範囲を拡大します。
脆弱コード例 2
void foo(int x) {
if (x*x != (0x7fff*0x7ffff)) {
}
}
上記の例は若干複雑で、式とリテラル式の両方に部分式が含まれています。ただし、リテラル式は、これを4 バイト整数では保持できない整数と評価します。Klocwork は、2 行目に欠陥を生成します。
修正コード例 2
void foo(int x) {
long long x_sqr = (long long)x*x;
if (x_xqr != (0x7fff*0x7ffffLL)) {
}
}
"x*x" の値が "LL" が接頭辞として付けられたリテラル 0x7ffff と共に適切な型キャストで計算され、比較は完全な 64 ビット比較になります。