Bug 13988 - scanf %f reads too many characters on non-matching "+.e" input
Summary: scanf %f reads too many characters on non-matching "+.e" input
Alias: None
Product: glibc
Classification: Unclassified
Component: stdio (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: 2.18
Assignee: Not yet assigned to anyone
Depends on:
Reported: 2012-04-18 05:40 UTC by Rich Felker
Modified: 2014-06-25 11:15 UTC (History)
0 users

See Also:
Last reconfirmed:
fweimer: security-


Note You need to log in before you can comment on or make changes to this bug.
Description Rich Felker 2012-04-18 05:40:28 UTC
I found this bug while investigating bug #12701 (my test cases attached there will reproduce it), but it seems to be a separate issue. Bug #12701 involves scanf wrongly accepting non-matching inputs.

Given the input "+.e", scanf (using %f) will correctly reject it as non-matching, but will leave the file position at an incorrect offset of 3 rather than 2. In other words, it's recognizing that a degenerate floating point value with no mantissa digits is invalid, but only after trying to parse all the way to the end of the exponent. This is incorrect per ISO C, which defines the input item 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".

The correct behavior would be to, upon encountering the "e" which is invalid after a degenerate mantissa, end the scan and leave the "e" unread in the stream.

Also, I just realized this error can be enlarged seemingly arbitrarily by appending a pseudo-exponent. For example, given "+.e" followed by N zeros, scanf will offset the file position by N+3 instead of by 2, an error of N+1, and thereby thoroughly consume an integer which could otherwise be read by the next call to scanf.
Comment 1 Andreas Schwab 2013-04-11 08:39:26 UTC
Fixed by 6ecec3b616aeaf121c68c1053cd17fdcf0cdb5a2