https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89312

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |diagnostic
             Status|UNCONFIRMED                 |RESOLVED
                 CC|                            |msebor at gcc dot gnu.org
           See Also|                            |https://gcc.gnu.org/bugzill
                   |                            |a/show_bug.cgi?id=80354
             Blocks|                            |88781
         Resolution|---                         |INVALID

--- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> ---
The warning says that the output of the " (" part of the format string (called
a directive, same as %s) may be truncated while snprintf is writing 2 bytes
(the length of the " (" string) into a region in the destination buffer whose
size GCC has computed to be between 1 and 255 bytes.  The phrasing isn't the
best but it's hard to come up with a concise sentence that describes the
problem without losing the relevant detail.

Below is a test case showing when the warning can trigger.  The size of the
destination array is 255, and so is the size of the argument of the fist %s
directive, a.  If strlen(a) were 254 (the longest string that fits), the call
would result in truncation.

The reason GCC warns for this is because most callers are unprepared for the
output of the function to be truncated (i.e., it would be a bug if it did). 
See bug 80354 comment 8 for an example (and the rest of the discussion there
for additional background).  To avoid the warning either provide a destination
buffer that can fit the longest output, or use precision to constrain the
amount of output that the %s directives can produce (e.g., %.200s to limit it
to at most 200 bytes), use the result of the function, or suppress the warning
by -Wno-format-truncation, either on the command line or via a pragma.

$ cat t.c && gcc -O2 -S -Wall t.c
char a[255];
char d[255];

void f (const char *s, int i)
{
  __builtin_snprintf (d, sizeof d, "%s (%s, %s-%d)", a, s, s, i);
}
t.c: In function ‘f’:
t.c:6:39: warning: ‘ (’ directive output may be truncated writing 2 bytes into
a region of size between 1 and 255 [-Wformat-truncation=]
    6 |   __builtin_snprintf (d, sizeof d, "%s (%s, %s-%d)", a, s, s, i);
      |                                       ^~
t.c:6:3: note: ‘__builtin_snprintf’ output 8 or more bytes (assuming 262) into
a destination of size 255
    6 |   __builtin_snprintf (d, sizeof d, "%s (%s, %s-%d)", a, s, s, i);
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88781
[Bug 88781] [meta-bug] bogus/missing -Wstringop-truncation warnings

Reply via email to