Bug 61511 - scanf man page is incomplete re out-of-range integer conversions
Summary: scanf man page is incomplete re out-of-range integer conversions
Status: NEW
Alias: None
Product: Documentation
Classification: Unclassified
Component: man-pages (show other bugs)
Hardware: All Linux
: P1 normal
Assignee: documentation_man-pages@kernel-bugs.osdl.org
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-09-16 20:04 UTC by Ian Pilcher
Modified: 2015-10-04 21:09 UTC (History)
1 user (show)

See Also:
Kernel Version:
Subsystem:
Regression: No
Bisected commit-id:


Attachments

Description Ian Pilcher 2013-09-16 20:04:25 UTC
Unless I'm missing it, the scanf man page doesn't really specifically address the result of an out-of-range integer conversion -- e.g. sscanf("9999999999999999999999999999999", "%d", &i).

The ERRORS section, however, says this:

 ERANGE The result of an integer conversion would exceed the size that
              can be stored in the corresponding integer type.

This is definitely *not* the behavior that I'm seeing.  Instead, sscanf is returning 1 and -1 is assigned to i.
Comment 1 walter 2013-09-16 21:27:34 UTC
Am 16.09.2013 22:04, schrieb bugzilla-daemon@bugzilla.kernel.org:
> sscanf("9999999999999999999999999999999", "%d", &i).


please try this code:

#include <stdio.h>
#include <errno.h>
int main()
{
        int ret,i;
        ret=sscanf("9999999999999999999999999999999", "%d", &i);
        perror("scanf");
        printf("ret=%d i=%d\n",ret,i);
        return 0;
}

re,
 wh
Comment 2 Ian Pilcher 2013-09-16 21:48:49 UTC
(In reply to walter from comment #1)
> please try this code:
> 
> #include <stdio.h>
> #include <errno.h>
> int main()
> {
>         int ret,i;
>         ret=sscanf("9999999999999999999999999999999", "%d", &i);
>         perror("scanf");
>         printf("ret=%d i=%d\n",ret,i);
>         return 0;
> }

scanf: Numerical result out of range
ret=1 i=-1

So it is setting errno, but it's still returning 1.  That's just weird.  (But allowed, since the behavior is undefined in this case.)

Perhaps the ERANGE section could note that it can occur even when the function does not return EOF.
Comment 3 Jon Harper 2015-10-04 21:09:00 UTC
strtod(3) has the following note:
NOTES
       Since 0 can legitimately be returned on both success and failure, the calling program should set errno to 0 before the call, and
       then determine if an error occurred by checking whether errno has a nonzero value after the call.

Maybe add the same note to scanf(3) ?


Also, the example program from scanf(3) is:
           char *p;
           int n;

           errno = 0;
           n = scanf("%m[a-z]", &p);
           if (n == 1) {
               printf("read: %s\n", p);
               free(p);
           } else if (errno != 0) {
               perror("scanf");
           } else {
               fprintf(stderr, "No matching characters\n");
           }

which suggests checking for the return value of scanf before checking for errno, which is wrong in the integer overflow case as scanf returns 1. Change the order of the checks ?


Also, for scanf, it doesn't set i to a constant value (adapting the example program to read an int):
jon@zog:~$ cat dez.c 
#include "stdlib.h"
#include "stdio.h"
#include "errno.h"

int main() {
           int res;
           int n;

           errno = 0;
           n = scanf("%d", &res);
           if (n == 1) {
               printf("read: %d\n", res);
           } else if (errno != 0) {
               perror("scanf");
           } else {
               fprintf(stderr, "No matching characters\n");
           }
}

jon@zog:~$ for ((i=0; i<30; i++)); do echo "$((10**i -1))" | ./dez; done
read: 0
read: 9
read: 99
read: 999
read: 9999
read: 99999
read: 999999
read: 9999999
read: 99999999
read: 999999999
read: 1410065407
read: 1215752191
read: -727379969
read: 1316134911
read: 276447231
read: -1530494977
read: 1874919423
read: 1569325055
read: -1486618625
read: -1981284353
read: 1661992959
read: -559939585
read: -1304428545
read: -159383553
read: -1593835521
read: 1241513983
read: -469762049
read: -402653185
read: 268435455
read: -1610612737

Note You need to log in before you can comment on or make changes to this bug.