Linux fprintf,错误:格式不是字符串文字且没有格式参数 [-Werror=format-security
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17260409/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
fprintf, error: format not a string literal and no format arguments [-Werror=format-security
提问by
when I try to compile fprintf(stderr,Usage)
on Ubuntu I got this error:
当我尝试fprintf(stderr,Usage)
在 Ubuntu上编译时出现此错误:
error: format not a string literal and no format arguments [-Werror=format-security
but when I compiled that on other linux distributions (RedHat, Fedora, SUSE) that is compiled successfully.
但是当我在其他编译成功的 Linux 发行版(RedHat、Fedora、SUSE)上编译它时。
Anyone has an idea?
有人有想法吗?
采纳答案by nos
You should use fputs(Usage, stderr);
你应该使用 fputs(Usage, stderr);
There is no need to use fprintf if you arn't doing formatting. If you want to use fprintf, use fprintf(stderr, "%s", Usage);
如果您不进行格式化,则无需使用 fprintf。如果要使用 fprintf,请使用fprintf(stderr, "%s", Usage);
The default compiler flagson Ubuntu includes -Wformat -Wformat-security
which is what gives this error.
Ubuntu 上的默认编译器标志包括-Wformat -Wformat-security
导致此错误的原因。
That flag is used as a precaution against introducing security related bugs, imagine what would happen if you somehow did this:
该标志用作防止引入与安全相关的错误的预防措施,想象一下如果您以某种方式这样做会发生什么:
char *Usage = "Usage %s, [options] ... ";
...
fprintf(stderr, Usage);
This would be the same as
fprintf(stderr, "Usage %s, [options] ... ]");
which is wrong.
这与fprintf(stderr, "Usage %s, [options] ... ]");
哪个错误相同
。
Now the Usage
string includes a format specifier, %s
, but you do not provide that argument to fprintf
, resulting in undefined behavior, possibly crashing your program or allowing it to be exploited. This is more relevant if the string you pass to fprintf comes from user input.
现在该Usage
字符串包含一个格式说明符 ,%s
但您没有向 提供该参数fprintf
,从而导致未定义的行为,可能会导致您的程序崩溃或允许其被利用。如果您传递给 fprintf 的字符串来自用户输入,则这更相关。
But if you do fprintf(stderr,"%s", "Usage %s, [options] ... ]");
There is no such problem. The 2. %s
will not be interpreted as a format specifer.
gcc can warn about this, and the default Ubuntu compiler flags makes it a compiler error.
但是如果你这样做fprintf(stderr,"%s", "Usage %s, [options] ... ]");
就不会有这样的问题。2.%s
不会被解释为格式说明符。gcc 可以对此发出警告,默认的 Ubuntu 编译器标志使其成为编译器错误。
回答by R.. GitHub STOP HELPING ICE
Use fputs(Usage)
or fprintf(stderr, "%s", Usage)
. The idiom of passing a message string to a printf
-family function is dangerous because, unless it's known not to contain format specifiers, any possible format specifiers in the string will be interpreted and result in undefined behavior (since they have no arguments corresponding to them), and this will almost always translate into security bugs.
使用fputs(Usage)
或fprintf(stderr, "%s", Usage)
。将消息字符串传递给printf
-family 函数的习惯用法是危险的,因为除非已知不包含格式说明符,否则字符串中任何可能的格式说明符都将被解释并导致未定义的行为(因为它们没有对应的参数) ,这几乎总是会转化为安全漏洞。
回答by BobC
It is perfectly correct to use fprintf()
with only two arguments. As the function definition clearly indicates, all arguments after the second are optional.
fprintf()
仅使用两个参数是完全正确的。正如函数定义清楚地表明的那样,第二个之后的所有参数都是可选的。
When the second argument does not contain a format clause, this warning actually becomes a bug, one that was introduced into GCC because of a BAD assumption that the second argument to fprintf()
would alwayscontain a format clause. There is nothing that is true about that assumption. This was a flawed decision, a bug, that was repaired in newer versions of GCC, which actually inspect the second argument to ensure the proper number and types of additional arguments are present when required.
当第二个参数不包含格式条款,此警告实际上变成了一个bug,即引入GCC因为一个坏的假设是,第二个参数之一fprintf()
将始终包含格式条款。这个假设没有任何事实是正确的。这是一个有缺陷的决定,一个错误,在较新版本的 GCC 中修复,它实际上检查第二个参数以确保在需要时存在正确数量和类型的附加参数。
Mixing fputs()
and fprintf()
calls is asking for bugs. Plus it just makes the code uglier. It is much cleaner to use fprintf()
everywhere, so long as you are also using a recent and sane GCC.
混合fputs()
和fprintf()
调用是在寻找错误。此外,它只会使代码更丑。fprintf()
只要您还使用最新且正常的 GCC,在任何地方使用它都会更干净。
The moral of this story is simple: Never modify good code to make a bad compiler happy.
这个故事的寓意很简单:永远不要为了让糟糕的编译器高兴而修改好的代码。