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