Cppcheck为scanf显示以下警告:
Message: scanf without field width limits can crash with huge input data. To fix this error message add a field width specifier:
%s => %20s
%i => %3i
Sample program that can crash:
#include
int main()
{
int a;
scanf("%i", &a);
return 0;
}
To make it crash:
perl -e 'print "5"x2100000' | ./a.out
我无法崩溃这个程序输入"巨大的输入数据".我应该输入什么才能让这次崩溃?我也不明白这个警告中最后一行的含义:
perl -e ...
最后一行是一个示例命令,用于演示示例程序的崩溃.它实质上导致perl打印2.100.000次"5",然后将其传递给程序"a.out"的stdin(这意味着是编译的示例程序).
首先,scanf()应该仅用于测试,而不是在现实世界的程序中由于几个问题而无法正常处理(例如,询问"%i"但用户输入"12345abc"("abc"将保留在标准输入和可能导致以下输入被填充,而用户无法更改它们).
关于这个问题:scanf()会知道它应该读取整数值,但它不知道它可以多长时间.指针可以指向16位整数,32位整数,或64位整数或更大的东西(它不知道关闭).具有可变数量的参数(用其定义...)的函数不知道传递的元素的确切数据类型,因此它必须依赖于格式字符串(格式标记的原因不是可选的,就像在C#中您只是编号一样,例如"{0} {1} {2}").而如果没有一个给定长度有承担一定的长度,这可能是与平台相关,以及(使使用更加取消保存功能).
通常,认为它可能有害并且是缓冲区溢出攻击的起点.如果您想保护并优化您的计划,请先将其替换为替代方案.