Bug 93627 - inconsistencies between sprintf and strcpy overflow warnings
Summary: inconsistencies between sprintf and strcpy overflow warnings
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 10.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks: Wstringop-overflow
  Show dependency treegraph
 
Reported: 2020-02-07 17:44 UTC by Martin Sebor
Modified: 2020-02-07 17:44 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Sebor 2020-02-07 17:44:10 UTC
-Wformat-overflow diagnoses sprintf calls that might overflow the destination based solely on the size of the array where the string argument to a %s directive is stored, as in f() below.  (-Wformat-truncation then diagnoses the possible truncation of the argument.)

But -Wstringop-overflow doesn't diagnose the equivalent potential overflow in calls to strcpy (and -Wstringop-truncation likewise doesn't diagnose the truncation in calls to strncpy -- its interpretation of truncation is different from -Wformat-truncation: a missing nul rather than cutting off the trailing part of the source string).

This is inconsistent and probably not terribly helpful to users, especially when they're dealing with a warning for code that's in reality safe (but GCC doesn't see it).

$ cat z.c && gcc -O2 -S -Wall -Wextra -Wpedantic z.c
char a[8], b[16];

void f (void)
{
  __builtin_sprintf (a, "%s", b);                // -Wformat-overflow
}

void fn (void)
{
  __builtin_snprintf (a, sizeof a, "%s", b);     // -Wformat-truncation
}


void g (void)
{
  __builtin_strcpy (a, b);                       // missing warning
}

void gn (void)
{
  __builtin_strncpy (a, b, sizeof a - 1);        // no warning (?)
  a[sizeof a - 1] = 0;
}
z.c: In function ‘f’:
z.c:5:26: warning: ‘%s’ directive writing up to 15 bytes into a region of size 8 [-Wformat-overflow=]
    5 |   __builtin_sprintf (a, "%s", b);                // -Wformat-overflow
      |                          ^~   ~
z.c:5:3: note: ‘__builtin_sprintf’ output between 1 and 16 bytes into a destination of size 8
    5 |   __builtin_sprintf (a, "%s", b);                // -Wformat-overflow
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
z.c: In function ‘fn’:
z.c:10:37: warning: ‘%s’ directive output may be truncated writing up to 15 bytes into a region of size 8 [-Wformat-truncation=]
   10 |   __builtin_snprintf (a, sizeof a, "%s", b);     // -Wformat-truncation
      |                                     ^~   ~
z.c:10:3: note: ‘__builtin_snprintf’ output between 1 and 16 bytes into a destination of size 8
   10 |   __builtin_snprintf (a, sizeof a, "%s", b);     // -Wformat-truncation
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~