fopen_s如何比fopen更安全? [英] How can fopen_s be more safe than fopen?

查看:367
本文介绍了fopen_s如何比fopen更安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为 Windows 平台开发遗留代码。当我在 VS2013 中编译代码时,它给出以下警告:

I'm working on legacy code for Windows platform. When I compile the code in VS2013, it give following warning:


错误C4996 :' fopen ':此函数或变量可能不安全。考虑改用 fopen_s 。要禁用弃用,请使用_CRT_SECURE_NO_WARNINGS。有关详细信息,请参见在线帮助。

error C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details."

它还会对 sprintf 。我知道 sprintf_s 由于缓冲区溢出比sprintf更安全。

And it will also give samiliar warning for sprintf. I understand sprintf_s is more safe than sprintf because of buffer overflow.

但是 fopen_s 比<$ c更安全$ c> fopen ,因为 fopen 不接受缓冲区,所以没有缓冲区溢出的机会。任何人都可以提供案件 fopen 是不安全的,而 fopen_s 是安全的吗?

But how can be fopen_s be more safe than fopen, there is no chance of buffer overflow because fopen doesn't accept an buffer. Can anyone provide an case fopen is unsafe, and fopen_s is safe?

推荐答案

在这种情况下, s 并不代表安全,它代表安全性得到了增强。对于 fopen_s ,则在尝试打开文件之前检查参数的有效性。

The s doesn't stand for "safe" in this case, it stands for "security enhanced". For fopen_s, the parameters are checked for validity before attempting to open the file.

使用 fopen ,您可以为文件名传递一个NULL指针,所有内容很可能会崩溃。 fopen_s 没有帽子问题(a)

With fopen, you can pass a NULL pointer for the filename and everything will most likely fall to pieces. fopen_s doesn't have that problem (a).

请记住,这些边界检查接口如 fopen_s 是ISO标准的可选部分,详见附件K(无论如何,还是C11)。不需要提供的实现,坦白地说, fopen 和许多其他所谓的不安全函数,如果您知道的话,则是绝对安全的

Keep in mind that these bounds checking interfaces like fopen_s are an optional part of the ISO standard, detailed in Annex K (as at C11, anyway). Implementations are not required to provide them and, to be honest, fopen, and many other so-called unsafe functions, are perfectly safe if you know what you're doing as a coder.

有趣的是, fopen_s 会为您捕获NULL指针,但是不是无效的指针,因此为什么它的安全性得到增强而不是安全-如果传递无效但非NULL的指针,仍然会造成一些损害。

It's interesting to note that fopen_s will trap NULL pointers for you but not invalid pointers, hence why it's security enhanced rather than safe - you can still cause some damage if you pass an invalid but non-NULL pointer.

其他安全功能仅当您传递正确的大小时,这才迫使您提供目标缓冲区大小也是安全的。

Other "safe" functions which force you to provide destination buffer sizes are also safe only as long as you pass the right size. Pass something too big and all bets are off.

(a) C11 K.3.5.2.1 fopen_s函数

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




运行时间约束

streamptr,文件名或模式均不应为空指针。

None of streamptr, filename, or mode shall be a null pointer.

如果存在运行时约束违反,fopen_s不会尝试打开文件。此外,如果streamptr不是空指针,则fopen_s将* streamptr设置为空指针。

If there is a runtime-constraint violation, fopen_s does not attempt to open a file. Furthermore, if streamptr is not a null pointer, fopen_s sets *streamptr to the null pointer.

C11 7.20.5.3 fopen函数,该函数指出文件名和模式都必须都指向一个字符串,但不指定如果提供NULL指针会发生什么情况(大多数实现可能会崩溃并返回null指针取消引用)。

Contrast that with C11 7.20.5.3 The fopen function which states that the filename and mode must both point to a string but don't specify what happens if you provide a NULL pointer (most implementations would likely crash with a null pointer dereference).

这篇关于fopen_s如何比fopen更安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆