c++ write fopen_sはどのようにしてfopenより安全ですか?



microsoft fopen_s (1)

この場合、 sは「安全」を表すものではなく、「セキュリティ強化」の略です。 fopen_sでは、ファイルを開く前にパラメータの妥当性がチェックされます。

fopenを使うと、ファイル名にNULLポインタを渡すことができ、すべてが断片化する可能性が高くなります。 fopen_sはその問題がありません(a)

fopen_sような境界チェックインタフェースはISO標準のオプション部分であり、附属書K(C11のように)に詳述されていることに留意してください。 実装にはそれらを提供する必要はありません。正直なところ、 fopenやその他のいわゆる安全でない機能の多くは、あなたがコーダーとして何をしているのかを知っていれば完全に安全です。

興味深いのは、 fopen_sがNULLポインタをトラップしますが、無効なポインタではないことです。なぜなら、安全ではなくセキュリティが強化されている理由です。無効なポインタでもNULLポインタを渡せば、

宛先バッファサイズを指定するように強制するその他の「安全な」関数は、正しいサイズを渡す限り、安全です。 あまりにも大きなものを渡すと、すべてのベットはオフになります。

(a) C11 K.3.5.2.1 The fopen_s function

errno_t fopen_s (
    FILE * restrict * restrict streamptr,
    const char * restrict      filename,
    const char * restrict      mode);

実行時制約

streamptr、filename、またはmodeのいずれもNULLポインタでなければなりません。

実行時制約の違反がある場合、fopen_sはファイルを開こうとしません。 さらに、streamptrがヌルポインタでない場合、fopen_sは* streamptrをヌルポインタに設定します。

C11 7.20.5.3 The fopen functionと対照的にC11 7.20.5.3 The fopen functionファイル名とモードが両方とも文字列を指していなければならないが、NULLポインタを与えると何が起きるかを指定してはいけないC11 7.20.5.3 The fopen function (ほとんどの実装はヌルポインタ逆参照でクラッシュする可能性が高い)。

私は、 Windowsプラットフォームのレガシーコードに取り組んでいます。 VS2013でコードをコンパイルすると、次の警告が表示されます。

エラーC4996: ' fopen ':この関数または変数が危険です。 代わりにfopen_sを使用することを検討してfopen_s 。 廃止予定を無効にするには、_CRT_SECURE_NO_WARNINGSを使用してください。 詳細はオンラインヘルプを参照してください。

また、 sprintfよく似た警告が表示されます。 私はsprintf_sがバッファオーバーフローのためにsprintfより安全だと理解しています。

しかし、どのようにしてfopen_s fopenより安全にすることができますか? fopenはバッファを受け入れないので、バッファオーバーフローの可能性はありません。 誰もがfopenは安全ではない、そしてfopen_sは安全です。





tr24731