NUM.OVERFLOW.DF
可能的数值溢出或环绕
NUM.OVERFLOW.DF 检查器会检测算术运算中可能出现的数值溢出或环绕情况。
漏洞与风险
数值溢出情况可能导致未定义的行为。此外,溢出会损害程序的可靠性和安全性。
漏洞代码示例 1
复制
#include <stdio.h>
void f()
{
unsigned short unA, unB;
unsigned short unRet = 0;
unA = 40000;
unB = 30000;
unRet = unA + unB;
}
在以上示例中,Klocwork 报告第 9 行出现 NUM.OVERFLOW.DF 缺陷,因为在使用 16 位 unsigned short 的平台上,算术运算(加法)的结果超出了 unsigned short 的范围。
修正代码示例 1
复制
typedef unsigned long long uint64_t;
typedef unsigned int uint32_t;
uint64_t foo(uint32_t x, uint32_t y) {
uint64_t z;
z = (uint64_t) ( x ) * y;
z = (uint64_t) ( y ) * 1000000U; //or: y*1000000ULL
return z;
}
合规解决方案将在执行算术运算之前检查加法运算是否会超出范围,借此确保加法运算永远不会溢出。
漏洞代码示例 2
复制
#include <stdio.h>
void g()
{
signed int lX, lY;
unsigned long long llZ = 0;
lX = 2000000000;
lY = 2000000000;
llZ = (unsigned long long)(lX * lY);
}
在此示例中,Klocwork 报告第 8 行出现 NUM.OVERFLOW.DF 缺陷,因为在使用 32 位或以下 signed int 的平台上,乘法运算会先在 32 位 (signed int) 中执行,然后才转换为 unsigned long long,这会导致溢出。
修正代码示例 2
复制
#include <stdio.h>
void g()
{
signed int lX, lY;
unsigned long long llZ = 0;
lX = 2000000000;
lY = 2000000000;
llZ = (unsigned long long) (lX) * lY;
}
在以上符合要求的示例中,变量 lX 首先进行向上转换,这使得 lY 自动提升,最终对 unsigned long long(64 位)执行乘法运算,从而避免了溢出的发生。
相关检查器
- NUM.OVERFLOW
-
MISRA.COMP.WRAPAROUND
扩展
此检查器无法进行扩展。