This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Unexpected -Wformat-truncation warnings


On 03/02/2018 08:00 AM, Mason wrote:
On 02/03/2018 15:38, Jonathan Wakely wrote:

On 2 March 2018 at 14:27, Mason wrote:

I am confused by both of these warnings.
I am aware that adding two 60-char strings might overflow an 80-char buffer,
which is why I'm using snprintf.

In which case the output would be truncated instead of overflowing,
and that's what the warning says.

I'm not sure these warnings are very helpful. What am I missing?
(I may have oversimplified the testcase.)

I think the point is that although you avoid undefined behaviour, you
might still not get the output you expected.

To provide some context, I am using the following struct:

struct expr
{
	int val;
	char txt[60];
};

to store symbolic arithmetic expressions.

I start with simple symbolic constants "a", "b", "c", etc
and build up more complex expressions, such as "(a + b)" and "((a + b) * c)"

Actual code, for example,

	struct expr bak = tab[i];
	snprintf(tab[i].txt, 60, "(%s + %s)", bak.txt, tab[j].txt);

Is there a different way to write this code to avoid the warning(s) or should
I just disable Wformat-truncation?
(I hate disabling warnings, but this one looks irrelevant, in my situation.)

As Jon explained, the warning tries to help detect instances of
snprintf truncation that the program isn't prepared to handle.
The prototypical example is constructing a pathname for a file
with some sensitive information in a directory private to
the process.  Truncating the pathname could result in creating
a file in a parent directory that's world-readable, resulting
in unintended information disclosure.

If in your example truncation cannot happen then using snprintf
is unnecessary and sprintf would be sufficient (although I would
have expected -Wformat-overflow to warn).  If it can, then there
is no sign that the code is prepared to handle it.

To answer your question, there are a few ways to rewrite the code
to avoid the warning, including:

1) Use the precision to limit the amount of data each %s directive
   can result in to at most 28 bytes (%.28s).  This will suppress
   the warning but it may still result in truncation.
2) Check the value returned from snprintf and handle the possible
   truncation.  Here you need to use the return value (i.e., it's
   not enough to just assign to a variable and not use it).
3) Use some other function to concatenate the strings (e.g.,
   strcpy or strncpy).  This could result in buffer overflow
   or in truncation (and trigger -Wstringop-overflow or
   -Wstringop-truncation warnings if detected), and so you might
   need to handle that as well.

As Jeff mentioned, we have been discussing integrating the warning
with the strlen pass to help it gain access to the string lengths
compute by it.  It's expected that the integration will reduce
the rate or false positives when the strings are known to be
shorter.  It's an open question whether the current heuristic of
using the array size to compute the maximum string length for
unknown strings should then be moved to -Wstringop-truncation=2.

Martin

PS There's some discussion is a report of essentially the same
problem in pr78913.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]