Error: format string is not a string literal

24,842

Solution 1

Use:

printf("%s", str_a);

to get rid of the warning when -Wformat-security is enabled.

The diagnostic is informative to avoid format string vulnerability. For example:

strcpy(str_a, "%x%x%x%x");
printf(str_a);

would be equivalent to:

printf("%x%x%x%x");

which is missing the required arguments and can be used by an attacker to dump the stack (assuming str_a is under user control, which is not the case in your program, but gcc is not smart enough to figure).

Solution 2

Consider 3 printf() statements. Which can the compiler detect if a format mis-match exists?

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
}

Solution 3

This is not an error but a warning. When using printf to print a string you want something like printf("%s", str_a). Whenever you have a string in quotes (" ") it's a string literal this is what the warning means when it says not a string literal. I am not completely sure why you need to have a string literal but it is usually best to follow the compiler; someone else can probabally clarify the need for a string literal.

Solution 4

The other answers are better. But if all else fails, you can tell the compiler to ignore the error.

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat"
printf(str_a);
#pragma clang diagnostic pop

godbolt

Solution 5

If you were to do something like this:

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

int main() {
    char str_a[20];

    fgets(str_a, 20, stdin);
    printf(str_a);
}

And the user entered in A %s bad %n string, the user will be able to crash your program, and perhaps start a shell.

With this input, the user can effectively do this:

printf("A %s bad %n string");

The %s specifier causes the function to read from an invalid address, while the %n specifier causes it to write to an invalid address.

Share:
24,842
ShanZhengYang
Author by

ShanZhengYang

Updated on September 26, 2021

Comments

  • ShanZhengYang
    ShanZhengYang over 2 years

    I have written a simple program in C, which allocates memory for a string vector and then prints this.

    #include <stdio.h>
    #include <string.h>
    
    int main() {
        char str_a[20];
    
        strcpy(str_a, "Hello, world!\n");
        printf(str_a);
    }
    

    Using compiler gcc, this gives a compilation error:

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

    I do not understand why I am getting a warning. Can someone explain it to me?