C++ 使用std::ifstream进行输入验证
我正在使用以下方法读取文件:C++ 使用std::ifstream进行输入验证,c++,validation,ifstream,coverity,C++,Validation,Ifstream,Coverity,我正在使用以下方法读取文件: std::ifstream is( file_name ); std::string s; if( !is.good() ) { std::cout << "error opening file: " << file_name << std::endl; } else { while( !is.eof() ) { s.clear();
std::ifstream is( file_name );
std::string s;
if( !is.good() ) {
std::cout << "error opening file: " << file_name << std::endl;
} else {
while( !is.eof() ) {
s.clear();
is >> s;
if (s.empty()) continue;
if (s.size() < 1 || s.size()>0x7FFFFFFF ) {
std::cout << "implausible data" << std::endl;
continue;
}
char *ss = new char[ s.size() + 1 ]; // COVERITY bails out
// do something with the data
delete[]ss;
}
}
我知道我不能信任从文件中读取的任何数据,但在这个阶段我看不到如何验证数据。
我已经在检查s.size()
是否在错误行上方的if
-子句中的合理范围内(尽管相当大)
那么为什么coverity会向我发出警告呢
另外,我还应该应用哪些其他输入验证策略?在下一节中
if (s.empty())
continue;
if (s.size() < 1 || s.size() > 0x7FFFFFFF)
{
std::cout << "implausible data" << std::endl;
continue;
}
char * ss = new char[s.size() + 1];
在这里,分析器很容易判断length
不会改变其值
围绕静态分析器工具的局限性编写这样的代码是否值得讨论。政府不鼓励它
不要仅仅为了安抚静态分析工具(如lint、clang和GCC)而使程序变得丑陋,并使用额外的警告选项,如-Wconversion
和-Wundef
。这些工具有助于发现bug和不清楚的代码,但它们也会产生大量的错误警报,以至于使用不必要的强制转换、包装和其他复杂操作使它们保持沉默会损害可读性。例如,请不要将强制类型转换插入void或调用to do nothing函数仅仅用于安抚lint checker
就我个人而言,只要代码的可读性不受太大影响,我就不会觉得太糟糕。在极端情况下,添加一条注释来解释为什么事情是这样做的可能是一个好主意。不应该在
eof()上循环。
。与其测试s.empty()
不如测试读取是否成功:而(is>>s){/*读取s在这里成功*/…}
可能代码分析器没有意识到s.size()
将在所有三个调用上返回相同的值。您是否尝试将返回值分配给变量并使用该变量?此外,在32位系统上,您无法分配0x8000000
字节,但您的代码会尝试。也许这就是问题所在?您需要将最大值再降低一点吗?@5gon12eder您的技巧确实解决了coverity的问题。
if (s.empty())
continue;
if (s.size() < 1 || s.size() > 0x7FFFFFFF)
{
std::cout << "implausible data" << std::endl;
continue;
}
char * ss = new char[s.size() + 1];
const std::size_t length = s.size();
if (!length)
continue;
if (length < 1 || length > 0x7FFFFFFF)
{
std::cout << "implausible data" << std::endl;
continue;
}
char * ss = new char[length + 1];