Re: -Wformat-overflow works strangely with struct members

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 07/07/2017 07:05 AM, Basin Ilya wrote:
Hi.
According to the description of -Wformat-overflow=2, "Unknown string arguments ... are assumed to be 1 character long".
However, when I pass a struct member of unknown length as a string argument, it's assumed to have the maximum possible length. Besides, I get this warning only if it's not
the first argument.

	#include <stdio.h>

	extern struct {
		char s[142];
	} x;

	extern char s[142];

	int main(int argc, char *argv[]) {
		char buf[12];
		sprintf(buf, "%c%s", 'x', x.s); // why warning?
		sprintf(buf, "%s", x.s); // why no warning then?
		sprintf(buf, "%c%s", 'x', s); // why no warning then?
		return 0;
	}

The first warning is issued when %s is passed an array argument
whose length isn't known.  Its size minus one is taken as the
length of the string.  This is done at both warning levels.
The logic behind it is if the string cannot be that long then
either a) the array is declared too big, or b) the %s directive
should specify the maximum length via the precision (e.g.,
"%.10s").  (There are cases where this isn't posible, such as
in sprintf("%s/%s", a, b) where both a and b are such arrays;
in those cases sprintf should be replaced with snprintf and
the possible truncation should be handled.)

With GCC 8 I get a warning for the second call to sprintf for
the same reason at both -Wformat-overflow levels.  I'm not sure
what prevents it in your case.  Please open a new bug for it and
either attach the translation unit for your test case (obtained
by preprocessing it with with -E) or remove the #include and
declare sprintf or use __builtin_sprintf.  (This should tell
us if the sprintf declaration in <stdio.h> is causing it.)

The warning is not issued for the third call because of bug
79538.  It's a limitation in the implementation which handles
member arrays but not non-members.  Please add your comments
on this case there if you have some.  I hope to fix it for
GCC 8.

Martin


_

        $ gcc -c -Wformat-overflow=1 test.c
        test.c: In function ‘main’:
        test.c:11:18: warning: ‘%s’ directive writing up to 141 bytes into a region of size 11 [-Wformat-overflow=]
          sprintf(buf, "%c%s", 'x', x.s); // why warning?
                          ^~        ~
        test.c:11:2: note: ‘sprintf’ output between 2 and 143 bytes into a destination of size 12
          sprintf(buf, "%c%s", 'x', x.s); // why warning?
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
_

gcc (GCC) 7.1.1 20170528





[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux