This is the mail archive of the glibc-bugs@sourceware.org mailing list for the glibc 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 libc/12667] New: fscanf silently converts signed to unsigned


http://sourceware.org/bugzilla/show_bug.cgi?id=12667

           Summary: fscanf silently converts signed to unsigned
           Product: glibc
           Version: 2.8
            Status: NEW
          Severity: normal
          Priority: P2
         Component: libc
        AssignedTo: drepper.fsp@gmail.com
        ReportedBy: alexander.enchevich@yahoo.com


The man page for the scanf functions says:

RETURN VALUE
       These  functions  return the number of input items successfully matched
       and assigned, which can be fewer than provided for, or even zero in the
       event of an early matching failure.


However, the fscanf function (I presume the other scanf funcs will behave the
same), when given a one-line file as input, which looks like:
-666666
will not detect that this is a signed number (see attached file test_fscanf.c,
around lines 84-96).

So a call to fscanf that looks like this:

    unsigned int    nInt = 0;
    ret = fscanf( fptr, " %u", &nInt );

will put will 4294300630 into nInt and will return 1, indicating that 1 field
was successfully scanned and assigned. This is incorrect, because the number
-666666 does not qualify as an "unsigned int". The above call should return
EOF, indicating that the request to scan one *unsigned integer* was NOT
successful, i.e. a "matching failure" occured; and nInt should not be modified. 

The matching failure is also defined in the man page as:
    ... matching failure, meaning that the input was inappropriate (see below).
                               ... If the next item of input does
    not match the conversion specification, the conversion fails â
    this is a matching failure.

This is exactly the case - the next item (the signed int -666666) not matching
the conversion specification (%u) and yet the call does not return EOF, as the
man page says it should on matching failure and does not even return 0 to
indicate it was unable to successfully scan any fields. It simply reads the
number as a *signed int* and then stores the result into the provided *unsigned
int* which explains the value 4294300630 in the example.

Interestingly, at the same time errno is set to 34 (Numerical result outside of
range) so some code inside the lib does have some idea that something went
wrong. This is yet another proof that this is a bug - you can't have errno set
if everything is had supposedly worked fine.

Also, attempting to scan a number bigger than MAXINT (signed and unsigned),
e.g. 6666666666 silently returns 0xFFFFFFFF as the scanned integer, which is
also a bug. (I can file a separate report for it if it is preferable?)

-- 
Configure bugmail: http://sourceware.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.


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