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 asfprintf(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
Std::Strings's Capacity(), Reserve() & Resize() Functions
How to Avoid Qt App.Exec() Blocking Main Thread
C++ Visual Studio Character Encoding Issues
How to Copy a .Txt File to a Char Array in C++
Why Is Std::Unordered_Map Slow, and How to Use It More Effectively to Alleviate That
How to Declare Constexpr Extern
Are Int8_T and Uint8_T Intended to Be Char Types
How to Create a New Operator in C++ and How
Why Cannot a Non-Member Function Be Used for Overloading the Assignment Operator
Identifying Primitive Types in Templates
What Is an In-Place Constructor in C++
Why Static Variable Needs to Be Explicitly Defined
How Would I Load a Png Image Using Win32/Gdi (No Gdi+ If Possible)
What Is the Datatype of String Literal in C++
Limiting Range of Value Types in C++