This is the mail archive of the gcc-bugs@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]

[Bug middle-end/77696] New: Confusing wording for -Wformat-length=


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

            Bug ID: 77696
           Summary: Confusing wording for -Wformat-length=
           Product: gcc
           Version: 7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: dmalcolm at gcc dot gnu.org
  Target Milestone: ---

Given this example from PR 77672...

****************************************************************************
cat v.c && ./xgcc -B. -c v.c -Wall
char d[3];

extern int sprintf (char*, const char*, ...);

void f (void) {
  sprintf (d, "%-s!", "abc");
}

void g (void) {
  sprintf (d, "%-s", "abc");
}
v.c: In function ‘f’:
v.c:6:19: warning: writing format character ‘!’ at offset 3 past the end of the
destination [-Wformat-length=]
   sprintf (d, "%-s!", "abc");
                   ^
v.c:6:3: note: format output 5 bytes into a destination of size 3
   sprintf (d, "%-s!", "abc");
   ^~~~~~~~~~~~~~~~~~~~~~~~~~
v.c: In function ‘g’:
v.c:10:15: warning: writing a terminating nul past the end of the destination
[-Wformat-length=]
   sprintf (d, "%-s", "abc");
               ^~~~~
v.c:10:3: note: format output 4 bytes into a destination of size 3
   sprintf (d, "%-s", "abc");
   ^~~~~~~~~~~~~~~~~~~~~~~~~
****************************************************************************

...I find the wording of these messages to be confusing.

Consider:
  v.c: In function ‘f’:
  v.c:6:19: warning: writing format character ‘!’ at offset 3 past the end of
the destination [-Wformat-length=]
     sprintf (d, "%-s!", "abc");
                     ^
  v.c:6:3: note: format output 5 bytes into a destination of size 3
     sprintf (d, "%-s!", "abc");
     ^~~~~~~~~~~~~~~~~~~~~~~~~~

My first interpretation of the first message:
  "writing format character ‘!’ at offset 3 past the end of the destination"
was that "!" is written 3 bytes after the end of the destination buffer i.e. at
d[6], whereas after several re-readings I think it means that "!" is written at
offset 3, and that offset 3 is after the end of the destination buffer.

Hence I think this should at least be reworded from:
  "writing format character ‘!’ at offset 3 past the end of the destination"
to:
  "writing format character ‘!’ at offset 3, which is after the end of the
destination"

Also, I found myself looking at the sprintf manpage to figure out what the
semantics of "format character '!'" were.  AIUI, in this context '!' is merely
an ordinary character to be copied unchanged.

If so, a better working would be:
  "writing character ‘!’ at offset 3, which is after the end of the
destination"

But better would be to emphasize that this is a buffer overflow, changing the
message to:
  "buffer overflow will occur when writing character ‘!’ (written to offset 3)"

A nice tweak would be to display the decl name in array form if the destination
supports it:
  "buffer overflow will occur when writing character ‘!’ to ‘p[3]’"

(would it need to be "will occur" vs "can occur"?)

The grammar in the supporting note:
  v.c:6:3: note: format output 5 bytes into a destination of size 3
     sprintf (d, "%-s!", "abc");
     ^~~~~~~~~~~~~~~~~~~~~~~~~~
seems to me to be poor - it's hard to tell whether "format" and "output" are
meant as nouns or verbs.

It could be changed from:
  format output 5 bytes into a destination of size 3
to:
  5 bytes will be written into a destination of size 3
which would be much clearer.

In terms of locations, the diagnostics should ideally show the location of the
destination decl as the location of the "note"; also, as a tweak, the first
location could show an underline from the initial part of the string up to the
caret showing the point where buffer overflow occurs:

  v.c: In function ‘f’:
  v.c:6:19: warning: buffer overflow will occur when writing format character
‘!’ to ‘p[3]’ [-Wformat-length=]
     sprintf (d, "%-s!", "abc");
                  ~~~^
  v.c:1:5: note: 5 bytes will be written into a destination of size 3
   char d[3];
        ^ ~

Ideally it would also underline the size of the buffer as a secondary range in
the note (as shown above), but sadly I don't think that location information is
available.

Similarly, for the 2nd pair of diagnostics, 

  v.c: In function ‘g’:
  v.c:10:15: warning: buffer overflow will occur when writing terminating nul
to ‘p[3]’ [-Wformat-length=]
     sprintf (d, "%-s", "abc");
                  ~~~^
  v.c:1:5: note: 4 bytes will be written into a destination of size 3
   char d[3];
        ^ ~

(using the trailing quote for the location of the NUL char; as per PR 77672)

Hope this is constructive

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