24

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

エラー C4996: ' fopen': この関数または変数は安全でない可能性があります。fopen_s代わりに使用することを検討してください。非推奨を無効にするには、_CRT_SECURE_NO_WARNINGS を使用します。詳細については、オンライン ヘルプを参照してください。」

また、同様の警告が表示されsprintfます。sprintf_sバッファ オーバーフローのため、sprintf よりも安全であると理解しています。

しかし、fopen_sが よりも安全であるにはどうすればよいでしょうか。バッファを受け入れないfopenため、バッファ オーバーフローの可能性はありません。ケースが安全ではなく、安全でfopenあることを誰でも提供できますか?fopenfopen_s

4

2 に答える 2

27

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

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

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

fopen_sNULL ポインターはトラップしますが、無効なポインターはトラップしないため、安全ではなくセキュリティが強化されていることに注意してください。

デスティネーションバッファサイズを提供することを強制する他の「安全な」関数も、適切なサイズを渡す限り安全です。大きすぎるものを渡すと、すべての賭けが無効になります。


(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 のいずれもヌル ポインターであってはなりません。

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

ファイル名とモードの両方が文字列を指している必要があるが、NULL ポインターを指定した場合に何が起こるかを指定しないというのと対照的ですC11 7.20.5.3 The fopen function(ほとんどの実装は、NULL ポインターの逆参照でクラッシュする可能性があります)。

于 2013-10-16T05:55:51.857 に答える