Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I get format not a string literal and no format arguments warning when I compile it on Linux. snprintf shows const char* for the third parameter. What is wrong to define const char *INTERFACE = "wlan0" then pass it to the function?

#include <stdio.h>
#include <net/if.h>
#include <string.h>

int main(int argc,char *argv[]){
    const char *INTERFACE        = "wlan0";
    struct ifreq ifr;

    memset(&ifr, 0, sizeof(ifr));
    snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), INTERFACE);

  return 0;
}
like image 733
sven Avatar asked Jan 13 '23 16:01

sven


2 Answers

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.

like image 200
Some programmer dude Avatar answered Jan 16 '23 20:01

Some programmer dude


The latter part of the warning ("and no format arguments") means that the string doesn't contain any %s, and thus there is no point in using snprintf() like you're doing it.

It's worth warning for since it can be a security risk, if the string argument is changable at runtime it's possible that a % can be "snuck in", which will lead to problems. Therefore it's better if the formatting string is hardcoded to "do what you want".

As has been said, there's no point in using snprintf() in this case at all.

like image 33
unwind Avatar answered Jan 16 '23 20:01

unwind