警告:格式不是字符串文字,也不是格式参数

Unz*_*nzi 43 c c++ format printf warnings

我想删除我在这行代码上发出的​​警告,

FILE *fil;
char *imp;
(...)
fprintf(fil,imp);
Run Code Online (Sandbox Code Playgroud)

事情就是当我这样做它在文件上写下我想要的,但如果我应用格式%s它不会,像这样

fprintf(fil, "%s", imp);
Run Code Online (Sandbox Code Playgroud)

San*_*uja 50

这个警告是gcc告诉你它无法验证printf样式函数(printf,fprintf ...等)的格式字符串参数的方法.当编译器无法手动查看字符串并确保在运行时期间所有内容都按预期运行时,将生成此警告.让我们看几个例子.

情况1.可以在编译时验证此字符串,编译器将允许它而不发出警告:

printf("This string has no format");
Run Code Online (Sandbox Code Playgroud)

情况2:对于这种情况,编译器可以检测到您具有格式说明符并将引发不同的警告.在我的机器上它说"警告:格式的参数太少".

// This will most probably crash your machine
printf("Not a safe string to %s"); 
Run Code Online (Sandbox Code Playgroud)

案例3.现在这有点你的情况.您正在运行在运行时生成的字符串并尝试打印它.您收到的警告是编译器警告您字符串中可能有格式说明符.比如说"坏%sdata".在这种情况下,运行时将尝试访问不存在的参数以匹配%s.更糟糕的是,这可能是用户试图利用您的程序(导致它读取不安全的数据).

char str[200];
scanf("%s", str)
printf(str)
Run Code Online (Sandbox Code Playgroud)

  • 要避免警告和可能的攻击向量,您还可以使用`printf("%s",str);`. (4认同)

ter*_*nus 17

虽然技术上用字符串调用类似printf的函数没有任何问题,但它仍然是不好的做法,因为字符串可能包含格式标记%s.例如,如果imp%s test坏事就会发生.

如果你只想打印imp没有格式化,你应该使用fputs(imp, fil)(注意反向参数).

  • 更糟糕的是:如果用户可以指定imp字符串,他可能能够使用%n格式标记来覆盖内存.这称为格式字符串攻击,可用于运行注入的代码. (9认同)
  • fputs可以写出一个字符串sans%格式. (3认同)