On 09.02.20 15:44, Mats Erik Andersson wrote:
> Hello there!
> 
> This note has its origin in a report received at bug-inetutils.
> The following test code for snprintf() is a simplyfied detection
> I have implemented as a warning-only test in Gnu Inetutils.
> My point is that Linux/glibc and kfreebsd/glibc triggers this
> warning, but OpenSolaris, OpenIndiana, FreeBSD, OpenBSD, NetBSD,
> and DragonflyBSD do not! Reading the replacement code for the
> Gnulib module snprintf, neither would your function, should it
> undergo the test. In conclusion, this is a case where the native
> glibc function snprintf() behaves worse than does your replacement.
> 
>   #define MESSAGE       "try a fool"
>   #define WRONG_MESSAGE "fool"
> 
>   char msg[sizeof (MESSAGE)] = "try a ";
> 
>   snprintf (msg, sizeof (msg), "%s%s", msg, WRONG_MESSAGE);
> 
>   if (!strcmp (msg, WRONG_MESSAGE))
>     printf ("Warning! snprintf got confused!\n");
> 
> Observe that `msg' is target, as well as source. POSIX mentions
> nothing about such a use case, but glibc will produce "fool",
> whereas all BSD unices as well as OpenSolaris descendants will
> produce "try a fool". Tacitly, POSIX would probably cry out
> a statement like "Undefined"!

s(n)printf declaration uses the restrict keyword. That basically means
that each of the pointers in the arguments points to the same block of
memory.

gcc -Wall tells you so (gcc 8 and upwards):
$ gcc -Wall msg.c -o msg
msg.c: In function ‘main’:
msg.c:11:13: warning: passing argument 1 to restrict-qualified parameter
aliases with argument 4 [-Wrestrict]
   11 |   snprintf (msg, sizeof (msg), "%s%s", msg, WRONG_MESSAGE);
      |             ^~~                        ~~~
msg.c:11:35: warning: ‘%s’ directive output may be truncated writing 4
bytes into a region of size between 1 and 11 [-Wformat-truncation=]
   11 |   snprintf (msg, sizeof (msg), "%s%s", msg, WRONG_MESSAGE);
      |                                   ^~
msg.c:11:3: note: ‘snprintf’ output between 5 and 15 bytes into a
destination of size 11
   11 |   snprintf (msg, sizeof (msg), "%s%s", msg, WRONG_MESSAGE);
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Except in rare cases, compiler warnings indicate that the programmer is
wrong. Turn them all (well, almost all) on !

Regards, Tim

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to