错误:格式字符串不是字符串文字

Sha*_*ang 6 c string gcc

我用C编写了一个简单的程序,它为字符串向量分配内存然后打印出来.

#include <stdio.h>
#include <string.h>

int main() {
    char str_a[20];

    strcpy(str_a, "Hello, world!\n");
    printf(str_a);
}
Run Code Online (Sandbox Code Playgroud)

使用编译器gcc,这会产生编译错误:

char_array2.c:8:12: warning: format string is not a string literal
      (potentially insecure) [-Wformat-security]
    printf(str_a);

1 warning generated.
Run Code Online (Sandbox Code Playgroud)

我不明白为什么我会收到警告.有人可以向我解释一下吗?

oua*_*uah 15

使用:

printf("%s", str_a);
Run Code Online (Sandbox Code Playgroud)

-Wformat-security启用后摆脱警告.

诊断信息可以避免格式字符串漏洞.例如:

strcpy(str_a, "%x%x%x%x");
printf(str_a);
Run Code Online (Sandbox Code Playgroud)

相当于:

printf("%x%x%x%x");
Run Code Online (Sandbox Code Playgroud)

缺少必需的参数,攻击者可以使用它来转储堆栈(假设str_a是在用户控制下,在程序中不是这种情况,但是gcc不够智能).


sud*_*ash 8

其他答案更好。但如果所有其他方法都失败,您可以告诉编译器忽略该错误。

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat"
printf(str_a);
#pragma clang diagnostic pop
Run Code Online (Sandbox Code Playgroud)

神箭

  • 哎呀。不:)有些警告应该被阅读并采取行动,而不是被忽略以允许草率的代码,而在 C 中你最不想要的就是草率的代码...... (2认同)

chu*_*ica 7

考虑3个printf()陈述.如果存在格式不匹配,编译器可以检测哪个?

void foo(const char *str_a,int x) {
  printf("Hello %d\n", x);  // Compiler sees this is good
  printf("Hello %d\n");     // Compiler sees this is bad --> warning/error
  printf(str_a, x);         // Compiler cannot tell - thus the warning
}
Run Code Online (Sandbox Code Playgroud)