Skip to contentSkip to conversation

New: scanf man page is misleading re out-of-range integer conversions

Bug 61511 bugzilla-daemon-590EEB7GvNiWaY/[email protected] 2 participants 6 messages Sep 16, 2013 – Oct 4, 2015 1 message not in the archive Man-pages: manual pages for Linux -- Sections 2, 3, 4, 5, and 7

lore
Share & tools
lore
#0 lore raw

https://bugzilla.kernel.org/show_bug.cgi?id=61511

Bug ID: 61511
Summary: scanf man page is misleading re out-of-range integer
conversions
Product: Documentation
Version: unspecified
Hardware: All
OS: Linux
Status: NEW
Severity: normal
Priority: P1
Component: man-pages
Assignee: documentation_man-pages-ztI5WcYan/[email protected]
Reporter: [email protected]
Regression: No

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.

Signature · 6 lines
You are receiving this mail because:
You are watching the assignee of the bug.
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): bug-61511-11311-3bo0kxnWaOQUvHkbgXJLS5sdmw4N0Rt+2LY78lusg7I@public.gmane.org/

#2 lore raw

Am 16.09.2013 22:04, schrieb bugzilla-daemon-590EEB7GvNiWaY/[email protected]:

Quoted 1 line

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
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#3 lore raw

[Bug 61511] scanf man page is misleading re out-of-range integer conversions

In reply to a message not in the archive

https://bugzilla.kernel.org/show_bug.cgi?id=61511

--- Comment #1 from walter <[email protected]> ---
Am 16.09.2013 22:04, schrieb bugzilla-daemon-590EEB7GvNiWaY/[email protected]:

Quoted 1 line

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

Signature · 6 lines
You are receiving this mail because:
You are watching the assignee of the bug.
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#4 lore raw

[Bug 61511] scanf man page is misleading re out-of-range integer conversions

In reply to a message not in the archive

https://bugzilla.kernel.org/show_bug.cgi?id=61511

--- Comment #2 from Ian Pilcher <[email protected]> --- (In reply to walter from comment #1)

Quoted 5 lines

please try this code:

#include <stdio.h>
#include <errno.h>
int main()

Quoted 7 lines
{
        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.

Signature · 6 lines
You are receiving this mail because:
You are watching the assignee of the bug.
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#5 lore raw

[Bug 61511] scanf man page is incomplete re out-of-range integer conversions

In reply to a message not in the archive

https://bugzilla.kernel.org/show_bug.cgi?id=61511

Ian Pilcher <[email protected]> changed:

What |Removed |Added
----------------------------------------------------------------------------

            Summary|scanf man page is           |scanf man page is
                   |misleading re out-of-range  |incomplete re out-of-range
                   |integer conversions         |integer conversions
Signature · 6 lines
You are receiving this mail because:
You are watching the assignee of the bug.
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#6 lore raw

[Bug 61511] scanf man page is incomplete re out-of-range integer conversions

In reply to a message not in the archive

https://bugzilla.kernel.org/show_bug.cgi?id=61511

Jon Harper <[email protected]> changed:

What |Removed |Added
----------------------------------------------------------------------------
CC| |[email protected]

--- Comment #3 from Jon Harper <[email protected]> --- 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
Signature · 6 lines
You are receiving this mail because:
You are watching the assignee of the bug.
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html