CWARN.NOEFFECT.OUTOFRANGE

範囲外の値

範囲外のリテラル定数による無効なバイナリ比較。

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 ビット比較になります。

関連チェッカー