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