11

Cppcheck は、次のようなコードで潜在的な問題を検出しました。

float a, b, c;
int count = sscanf(data, "%f,%f,%f", &a, &b, &c);

「フィールド幅制限のないscanfは、巨大なデータでクラッシュする可能性があります」と書かれています。そんなことがあるものか?それはいくつかの sscanf 実装の既知のバグですか? 数値が (数値的に) オーバーフローする可能性があることは理解していますが、どのようにしてプログラムがクラッシュするのでしょうか? それはcppcheckの誤検知ですか?

同様の質問を見つけました: scanf Cppcheck warningですが、答えは完全に満足できるものではありません。答えは型の安全性に言及していますが、それはここでは問題になりません。

4

3 に答える 3

7

私はCppcheck開発者です。

はい、これは奇妙なクラッシュです。「巨大なデータ」とは、数百万桁を意味します。

--verboseフラグを使用すると、cppcheckは実際には、Linuxコンピューターで通常クラッシュする小さなサンプルコードを記述します。

Ubuntu11.10コンピューターでセグメンテーション違反が発生してクラッシュするコード例を次に示します。

#include <stdio.h>

#define HUGE_SIZE 100000000

int main()
{
    int i;
    char *data = new char[HUGE_SIZE];
    for (int i = 0; i < HUGE_SIZE; ++i)
        data[i] = '1';
    data[HUGE_SIZE-1] = 0;
    sscanf(data, "%i", &i);
    delete [] data;
    return 0;
}

参考までに、Visual Studioでこのサンプルコードを試しても、クラッシュすることはありません。

コンパイルにはg++バージョン4.6.1を使用しました。

于 2012-02-15T14:49:45.950 に答える
4

セグメンテーション違反は glibc のバグのようです。

ubuntu 10.04でクラッシュするが、ubuntu 12.04で動作する同様のプログラムでこれをテストしました。

Daniel Marjamäki が言ったように、彼のプログラムは 11.10 でクラッシュします。バグはその間に修正されていると思います。

于 2012-06-12T14:34:51.387 に答える
1

OK、次のコードを検討してください。

int main(int argc, char *argv[]) {
    const char* data = "9999999999999999999999999.9999999999999999999999//i put alot more 9's there, this just to get the point through
    float a;
    int count = sscanf(data, "%f", &a);
    printf("%f",a);
}

このプログラムの出力は「inf」です - クラッシュはありません。そして、私はそこに大量の 9 を入れました。したがって、Cppcheck はこれについて単純に間違っているのではないかと思います。

于 2012-02-15T12:48:44.867 に答える