簡體   English   中英

使用std :: ifstream進行輸入驗證

[英]input validation with std::ifstream

我正在使用類似文件讀取文件:

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

當我使用靜態代碼分析工具coverage (免費版)分析以上代碼時,標有COVERITY的行崩潰了,並拋出錯誤:

 Untrusted value as argument (TAINTED_SCALAR)
   tainted_data: Passing tainted variable > s.size() + 1UL to a tainted sink.

我知道我不能信任從文件讀取的任何數據,但是在此階段我看不到如何驗證數據。 我已經檢查s.size()是在一個合理的(雖然相當大的)的范圍內if -clause上述錯誤行。

那么為什么隱蔽性向我發出警告?

另外,我應該采用其他哪些輸入驗證策略?

在以下部分

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

驗證邏輯依賴於以下重要事實: s.size()每次被調用時都將返回相同的值。 盡管在這種情況下,我們(人類)知道這是正確的,但是靜態代碼分析器可能無法實現這一點。

解決方法是嘗試引入局部變量並使用該變量。

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

在這里,分析儀很容易告訴您length不會改變其值。

圍繞靜態分析器工具的局限性進行這種編碼是否值得進行辯論。 GNU編碼標准不鼓勵這樣做。

不要僅用靜態警告分析工具(如lint,clang和GCC)加上諸如-Wconversion-Wundef類的額外警告選項來使程序變得丑陋。 這些工具可以幫助發現錯誤和不清楚的代碼,但是它們也可能生成大量錯誤警報,以至於由於不必要的強制轉換,包裝和其他復雜性而使它們靜音,從而損害了可讀性。 例如,請不要僅僅為了平整棉絨檢查器而將強制轉換插入void或不執行任何操作的調用。

就個人而言,只要代碼的可讀性不會受到太大影響,我就不會對此感到不滿意。 在極端情況下,添加注釋以解釋為什么事情以完成方式進行可能是個好主意。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM