Bug 12437 - scanf behavior differs from WG14/N1256 Committee Draft — Septermber 7, 2007
Summary: scanf behavior differs from WG14/N1256 Committee Draft — Septermber 7, 2007
Status: RESOLVED DUPLICATE of bug 12701
Alias: None
Product: glibc
Classification: Unclassified
Component: stdio (show other bugs)
Version: 2.13
: P2 normal
Target Milestone: ---
Assignee: Ulrich Drepper
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-01-25 20:01 IST by H.J. Lu
Modified: 2014-06-27 14:00 IST (History)
3 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
fweimer: security-


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description H.J. Lu 2011-01-25 20:01:40 IST
Page 300 in

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf

says "100e" shouldn't match "%f". But I got

[hjl@gnu-6 tmp]$ cat s.c
#include <stdio.h>

int main()
{
  int count;
  float quant;
  char buf[100];
  count = fscanf(stdin, "%f%s", &quant, buf);
  printf ("quant = %lf\n",quant );
  printf ("count = %d\n", count);
  printf ("string = %s\n", buf);
  return 0;
}
[hjl@gnu-6 tmp]$ gcc s.c
[hjl@gnu-6 tmp]$ cat x.input 
100ergs of energy
[hjl@gnu-6 tmp]$ ./a.out  < x.input 
quant = 100.000000
count = 2
string = rgs
[hjl@gnu-6 tmp]$ 

I was told that Windows and MacOS behave the same as glibc.
Comment 1 Ulrich Drepper 2011-01-25 20:45:56 IST
The implementation is correct.  The implementation must behave as if at most one character can be pushed back.  Since only after the 'r' is read the mistake is found the result is rgs for the string.
Comment 2 Rich Felker 2011-10-07 04:24:05 IST
This bug is valid. Nobody is claiming scanf should pushback two characters, but it needs to report a matching failure rather than accepting "100e" as if it were a valid floating point representation. The C standard could not be more explicit on this matter.
Comment 3 gmper 2012-09-28 04:53:12 IST
Why shouldn't the scanf() function read "100" from "100e" ?
If it shouldn't read even "100" from "100e" (according to the standard), what it should leave in the input stream after that matching failure ? What is the next character during the next call of a reading function ?
Comment 4 Rich Felker 2012-09-28 12:27:15 IST
> Why shouldn't the scanf() function read "100" from "100e" ?

Formally, because it's specified not to. See 7.19.6.2:

"An input item is read from the stream, unless the specification includes an n specifier. An input item is defined as the longest sequence of input characters which does not exceed any specified field width and which is, or is a prefix of, a matching input sequence.251) The first character, if any, after the input item remains unread.

... If the input item is not a matching sequence, the execution of the directive fails: this condition is a matching failure. ...

...

251) fscanf pushes back at most one input character onto the input stream. Therefore, some sequences that are acceptable to strtod, strtol, etc., are unacceptable to fscanf."

Conceptually, because scanf only has one character of "lookahead". "100e" is all read because it's a valid initial sequence of a floating point string. The next character (or EOF) is then inspected and seen not to match, and thus left unread. And the directive is required to fail. glibc basically does this except it wrongly makes the directive succeed and assigns a value to the invalid partial float string.
Comment 5 Florian Weimer 2014-06-27 14:00:25 IST
Duplicate of bug 12701.

*** This bug has been marked as a duplicate of bug 12701 ***