DBZ.ITERATOR
在除以零的运算中可能使用了循环迭代器
尝试在除法或模运算中使用零作为除数会导致运行时错误。错误处理或争用条件无效时,经常出现除以零的情况,并且通常会导致程序异常终止。在 C/C++ 代码中将值用作除法或模运算的除数之前,必须进行检查以确认值不为零。
DBZ 检查器会查找零常量值用作除法或模运算除数的实例。
DBZ.ITERATOR 检查器会标记以下情况:循环迭代器在循环执行中被赋值为零常数值,而该循环迭代器后续在不进行零值检查的情况下,可能被显式使用或传递到可能将其用作除法或模运算除数的函数。
漏洞与风险
整数除以零通常会导致进程失败或异常。运算也可能成功,但会给出错误答案。浮点数除以零则更为微妙,具体取决于编译器的实施情况。如果编译器遵循 IEEE 浮点标准 (IEEE 754),则浮点数除以零会得到明确的结果。然而,C 和 C++ 标准不会强制遵循 IEEE 754。因此,浮点数除以零在 C 和 C++ 中具有未定义的行为,可能导致进程失败或异常。
异常处理无效时,经常出现除以零的情况。为避免此漏洞,在将值用作除法或模运算的除数之前,检查该值是否为零。
漏洞代码示例
复制
int count_sum_of_custom_arithmetic_series()
{
int sum = 0;
for (int i = -10; i < 10; ++i) {
sum += 3628800 / i;
}
return sum;
}
Klocwork 针对第 5 行生成问题报告,指出在循环迭代期间循环迭代器 i 被赋值为零常量值,并且该值被用作除法运算的除数。除以零会产生无法预料的意外结果。
修正代码示例
复制
int count_sum_of_custom_arithmetic_series()
{
int sum = 0;
for (int i = -10; i < 10; ++i) {
if (i != 0) {
sum += 3628800 / i;
}
}
return sum;
}
前一代码段中的问题已修复:在第 5 行检查输入变量 size 是否有零常量值的异常情况,并防止在第 6 行的除法运算中使用值 0。
扩展
此检查器可通过 Klocwork 知识库进行扩展。有关详情,请参阅调整 C/C++ 分析。
限制
此检查器不处理计算为零的抽象符号表达式。这意味着此检查器检测不到涉及此类原因的缺陷。例如:
复制
int count_sum_of_custom_arithmetic_series()
{
int sum = 0;
for (int i = -10; i < 10; ++i) {
sum += 3628800 / (i - i); // Divide by zero will happen here since i - i = 0.Not detected by this checker.
}
return sum;
}
该检查器仅处理步长(或增量)为 +1 或 -1 的循环迭代器。这意味着该检查器不会检测到涉及步长不为 +1 或 -1 的循环迭代器的缺陷。例如:
复制
intcount_sum_of_custom_arithmetic_series_with_step_of_two()
{
int sum = 0;
for (int i = -10; i < 10; i += 2) {
sum += 3628800 / i; // Divide by zero will not be detected here since it the step of i is +2.
}
return sum;
}