Warning: Format Not a String Literal and No Format Arguments

c array - warning: format not a string literal

When using printf, the format string is better as a string literal than a variable:

printf("%s", str_a);

warning: format not a string literal and no format arguments

This warning is gcc's way of telling you that it cannot verify the format string argument to the printf style function (printf, fprintf... etc). This warning is generated when the compiler can't manually peek into the string and ensure that everything will go as you intend during runtime. Lets look at a couple of examples.

Case 1. This string can be verified at compile time and the compiler will allow it without warning:

printf("This string has no format");

Case 2: For this case, the compiler can detect that you have a format specifier and will raise a different warning. On my machine it said "warning: too few arguments for format".

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

Case 3. Now this is somewhat your case. You are taking a string generated at runtime and trying to print it. The warning you are getting is the compiler warning you that there could be a format specifier in the string. Say for eg "bad%sdata". In this case, the runtime will try to access a non-existent argument to match the %s. Even worse, this could be a user trying to exploit your program (causing it to read data that is not safe to read).

char str[200];
scanf("%s", str)
printf(str)

C program warning: format not a string literal and no format arguments

Don't use fprintf() if you want to print a constant string.

Use fputs(str, fp).

If you feel you must use fprintf(), add the formatting string i.e. use fprintf(fp, "%s", str);.

Warning format not a string literal and no format arguments not appearing on latest gcc version

This is not caused by a difference in GCC versions. Rather, Ubuntu has modified GCC to enable -Wformat -Wformat-security by default. If you pass those options on Arch Linux, you should see the same behaviour there.

Getting a “format not a string literal and no format arguments” warning while using GTK+2

The answer is quite simple.

You have to add "%s" to the arguments of the gtk_message_dialog_new() function like this:

static void show_message (gchar *message, GtkMessageType type) {
GtkWidget *dialog = gtk_message_dialog_new(NULL, 0, type,
GTK_BUTTONS_OK, "%s",
message);
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
}

Basically, the lack of "%s" is considered non-secure by gcc.

You can read more about it here:

  • warning: format not a string literal and no format arguments

  • http://cboard.cprogramming.com/linux-programming/148565-gtk_message_dialog_new-showing-literal-warning.html

format not a string literal and no format arguments [-Wformat-security]

Make the format string literal explicit:

printf("%s", str);

The same warning can be reproduced with the following snippet:

#include <stdio.h>

int main()
{
char str[] = "hello";
printf(str);
}

main.cpp:6:12: warning: format string is not a string literal (potentially insecure)
[-Wformat-security]

The compiler cannot verify if str contains a %s.

The first warning has a mismatch instead: insufficient format specifiers (e.g. another %s) in the string literal, since two additional argument follow.

fprintf, error: format not a string literal and no format arguments [-Werror=format-security

You should use 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);

The default compiler flags on Ubuntu includes -Wformat -Wformat-security which is what gives this error.

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.

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.

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.

C++: Format not a string literal and no format arguments

Simple - provide a format string:

sprintf(temp, "%s", constStack.top().c_str());

But much, much better:

string temp = constStack.top();

Error: format string is not a string literal

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).

snprintf - format not a string literal and no format arguments warning

It's nothing wrong (that's why it's a warning and not an error), it's just that the most common use of the printf family of function uses a literal format string.

Like:

snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", INTERFACE);

In your case you should probably be using e.g. memcpy instead:

#define MIN(a, b) ((a) < (b) ? (a) : (b))

memcpy(ifr.ifr_name, INTERFACE, MIN(strlen(INTERFACE) + 1, sizeof(ifr.ifr_name));

There's also strncpy which might work, but there is a case when it will not add the terminating '\0' character.



Related Topics



Leave a reply



Submit