Bug 79538 - missing -Wformat-overflow with %s and non-member array arguments
Summary: missing -Wformat-overflow with %s and non-member array arguments
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 7.0
: P3 normal
Target Milestone: ---
Assignee: Qing Zhao
URL:
Keywords: diagnostic
Depends on:
Blocks: Wformat-overflow
  Show dependency treegraph
 
Reported: 2017-02-15 18:38 UTC by Martin Sebor
Modified: 2018-05-10 21:06 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2017-03-13 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Sebor 2017-02-15 18:38:23 UTC
The -Wformat-overflow option detects the possible buffer overflow in function f below but missed the same possible overflow in function g.  The function it relies on to detect the sizes of the array, get_range_strlen() in gimple-fold.c, handles member arrays but not the non-member array case.

$ cat u.c && gcc -O2 -S -Wall -Wformat-overflow  u.c
char d[3];

struct S {
  char a3[3];
  char a4[4];
};

void f (int i, const struct S *p)
{
  const char *s = i < 0 ? p->a3 : p->a4;
  __builtin_sprintf (d, "%-s", s); 
}

char a3[3];
char a4[4];

void g (int i)
{
  const char *s = i < 0 ? a3 : a4;
  __builtin_sprintf (d, "%-s", s); 
}
u.c: In function ‘f’:
u.c:11:25: warning: ‘__builtin_sprintf’ may write a terminating nul past the end of the destination [-Wformat-overflow=]
   __builtin_sprintf (d, "%-s", s);
                         ^~~~~
u.c:11:3: note: ‘__builtin_sprintf’ output between 1 and 4 bytes into a destination of size 3
   __builtin_sprintf (d, "%-s", s);
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Comment 1 Martin Sebor 2017-03-13 21:03:30 UTC
Confirming my own bug and adjusting the Summary to make it clear that the problem isn't specific to global arrays and affects local arrays as well.  The following test case shows that.

$ cat z.c && gcc -O2 -S -Wall -Wextra -Wpedantic -fdump-tree-printf-return-value=/dev/stdout z.c
int main ()
{
  char d[3];
  char s[] = "abcd";

  __builtin_sprintf (d, "%-s", s);
  __builtin_printf ("%s\n", d);
}


;; Function main (main, funcdef_no=0, decl_uid=1794, cgraph_uid=0, symbol_order=0) (executed once)

z.c:6: __builtin_sprintf: objsize = 3, fmtstr = "%-s"
  Directive 1 at offset 0: "%-s"
    Result: 0, 0, -1, 9223372036854775807 (0, 0, -1, -1)
  Directive 2 at offset 3: "", length = 1

main ()
{
  char s[5];
  char d[3];

  <bb 2> [100.00%]:
  s = "abcd";
  __builtin_sprintf (&d, "%-s", &s);
  __builtin_puts (&d);
  d ={v} {CLOBBER};
  s ={v} {CLOBBER};
  return 0;

}
Comment 2 Qing Zhao 2017-11-20 16:20:31 UTC
this is because the routine "get_range_strlen" misses the handling of regular arrays. adding the support should fix this issue.
Comment 3 Paolo Carlini 2017-11-20 18:39:55 UTC
Qing is on it.
Comment 5 Qing Zhao 2017-12-14 20:21:12 UTC
this bug has been fixed in upstream. and is decided not back port to Gcc 7.
so close it as resolved