5

差出人man gets

get()は絶対に使用しないでください。事前にデータを知らずにgets()が読み取る文字数を知ることは不可能であり、gets()はバッファの終わりを超えて文字を格納し続けるため、使用するのは非常に危険です。これは、コンピュータのセキュリティを破るために使用されてきました。代わりにfgets()を使用してください。

ほとんどすべての場所で、同じ問題(バッファオーバーフロー/バッファオーバーラン)が発生scanfするはずの方法で使用されていることがわかります。この場合、この問題は存在しますか?マニュアルページにそれについての参照がないのはなぜですか?これをコンパイルするときにgccが警告しないのはなぜですか?scanf("%s",string)scanf-Wall

ps:フォーマット文字列で文字列の最大長をscanf:で指定する方法があることを私は知っています。

char str[10];
scanf("%9s",str);

編集:私は前のコードが正しいかどうかを判断するように求めていません。私の質問は、もしscanf("%s",string)常に間違っているのなら、なぜ警告がなく、マニュアルページにそれについて何もないのですか?

4

5 に答える 5

5

答えは、その警告を生成するコードをGCCで記述した人は誰もいないということです。

ご指摘のとおり、"%s"(フィールド幅なしの)特定のケースに対する警告は非常に適切です。

scanf()ただし、これは、、、およびの場合にのみ当てはまることに注意してvscanf()ください。このフォーマット指定子はとで完全に安全である可能性があるため、その場合は警告を発行しないでください。これは、既存の「scanf-style-format-string」分析コードに単純に追加することはできないことを意味します。これを「fscanf-style-format-string」オプションと「sscanf-style-format-string」オプションに分割する必要があります。fscanf()vfscanf()sscanf()vsscanf()

最新バージョンのGCCのパッチを作成すると、受け入れられる可能性が高くなると確信しています(もちろん、glibcヘッダーファイルのパッチも送信する必要があります)。

于 2010-06-05T03:45:41.740 に答える
4

使用gets()は決して安全ではありません。 scanf()あなたがあなたの質問で言ったように、安全に使うことができます。ただし、それを安全に使用しているかどうかを判断することは、コンパイラーが解決するのがより難しい問題です(たとえばscanf()、バッファーを渡し、引数として文字数をカウントする関数を呼び出す場合、それはできません伝えるために); その場合、あなたが何をしているのかを知っていると仮定する必要があります。

于 2010-06-04T20:29:47.277 に答える
3

コンパイラがのフォーマット文字列をscanf見ると、文字列が表示されます。これは、実行時にフォーマット文字列が入力されていないことを前提としています。GCCのような一部のコンパイラには、コンパイル時に入力された場合にフォーマット文字列を分析するための追加機能がいくつかあります。場合によっては実行時のオーバーヘッドが必要になるため、この追加機能は包括的ではありません。これは、Cなどの言語ではNO NOです。たとえば、この場合、追加の非表示コードを挿入せずに、安全でない使用法を検出できますか。

char* str;
size_t size;
scanf("%z", &size);
str = malloc(size);
scanf("%9s"); // how can the compiler determine if this is a safe call?!

もちろん、scanf読み取る文字数を指定し、文字列を保持するのに十分なメモリがある場合は、安全なコードを作成する方法があります。の場合、gets読み取る文字数を指定する方法はありません。

于 2010-06-04T20:35:21.943 に答える
1

scanfのマニュアルページにバッファオーバーランの可能性が記載されていない理由はわかりませんが、vanillascanfは安全なオプションではありません。かなり古いリンク-http://blogs.msdn.com/b/rsamona/archive/2005/10/24/484449.aspxは、これを事例として示しています。また、これを確認してください(gccではありませんが、有益です)-http://blogs.msdn.com/b/parthas/archive/2006/12/06/application-crash-on-replacing-sscanf-with-sscanf-s。 aspx

于 2010-06-04T20:35:31.363 に答える
-4

scanfは、読み込まれるデータの量に基づいてヒープにスペースを割り当てるだけの場合もあります。バッファを割り当てず、ヌル文字が読み込まれるまで読み取るので、バッファを上書きするリスクはありません。代わりに、ヌル文字が見つかるまで独自のバッファに読み込み、おそらく読み取りの最後にそのバッファを正しいサイズの別のバッファにコピーします。

于 2010-06-04T20:33:39.790 に答える