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;
     }
 }

针对以上示例的一次简单修正描述如下,声明 int 而非 unsigned char 为变量,从而扩大了 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 位比较。

相关检查器