Module Name: src Committed By: christos Date: Sat Jan 20 16:13:39 UTC 2024
Modified Files: src/common/lib/libc/stdlib: _strtoi.h src/lib/libc/stdlib: strtoi.3 strtonum.c strtou.3 Log Message: PR/57828: Alejandro Colomar: Prioritize test for ERANGE before testing for fully consuming the string. Adjust strtonum(3) to behave as before. Document the order of the tests and sync the man pages (I should really autogenerate one of the two man pages...) To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 src/common/lib/libc/stdlib/_strtoi.h cvs rdiff -u -r1.7 -r1.8 src/lib/libc/stdlib/strtoi.3 \ src/lib/libc/stdlib/strtou.3 cvs rdiff -u -r1.6 -r1.7 src/lib/libc/stdlib/strtonum.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/common/lib/libc/stdlib/_strtoi.h diff -u src/common/lib/libc/stdlib/_strtoi.h:1.2 src/common/lib/libc/stdlib/_strtoi.h:1.3 --- src/common/lib/libc/stdlib/_strtoi.h:1.2 Sun Jan 18 12:55:22 2015 +++ src/common/lib/libc/stdlib/_strtoi.h Sat Jan 20 11:13:39 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: _strtoi.h,v 1.2 2015/01/18 17:55:22 christos Exp $ */ +/* $NetBSD: _strtoi.h,v 1.3 2024/01/20 16:13:39 christos Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -100,26 +100,26 @@ INT_FUNCNAME(_int_, _FUNCNAME, _l)(const errno = serrno; #endif - if (*rstatus == 0) { - /* No digits were found */ - if (nptr == *endptr) - *rstatus = ECANCELED; - /* There are further characters after number */ - else if (**endptr != '\0') - *rstatus = ENOTSUP; - } + /* No digits were found */ + if (*rstatus == 0 && nptr == *endptr) + *rstatus = ECANCELED; if (im < lo) { if (*rstatus == 0) *rstatus = ERANGE; return lo; } + if (im > hi) { if (*rstatus == 0) *rstatus = ERANGE; return hi; } + /* There are further characters after number */ + if (*rstatus == 0 && **endptr != '\0') + *rstatus = ENOTSUP; + return im; } Index: src/lib/libc/stdlib/strtoi.3 diff -u src/lib/libc/stdlib/strtoi.3:1.7 src/lib/libc/stdlib/strtoi.3:1.8 --- src/lib/libc/stdlib/strtoi.3:1.7 Mon Jul 3 17:32:50 2017 +++ src/lib/libc/stdlib/strtoi.3 Sat Jan 20 11:13:39 2024 @@ -1,4 +1,4 @@ -.\" $NetBSD: strtoi.3,v 1.7 2017/07/03 21:32:50 wiz Exp $ +.\" $NetBSD: strtoi.3,v 1.8 2024/01/20 16:13:39 christos Exp $ .\" .\" Copyright (c) 1990, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -36,12 +36,12 @@ .\" Created by Kamil Rytarowski, based on ID: .\" NetBSD: strtol.3,v 1.31 2015/03/11 09:57:35 wiz Exp .\" -.Dd November 13, 2015 +.Dd January 20, 2024 .Dt STRTOI 3 .Os .Sh NAME .Nm strtoi -.Nd convert string value to an intmax_t integer +.Nd convert a string value to an intmax_t integer .Sh LIBRARY .Lb libc .Sh SYNOPSIS @@ -58,8 +58,7 @@ .Sh DESCRIPTION The .Fn strtoi -function -converts the string in +function converts the string in .Fa nptr to an .Ft intmax_t @@ -117,10 +116,11 @@ is taken as 10 (decimal) unless the next .Ql 0 , in which case it is taken as 8 (octal). .Pp -The remainder of the string is converted to a +The remainder of the string is converted to an .Em intmax_t value in the obvious manner, -stopping at the first character which is not a valid digit +stopping at the end of the string +or at the first character which is not a valid digit in the given base. (In bases above 10, the letter .Ql A @@ -201,6 +201,12 @@ or the range given was invalid, i.e. > .Fa hi . .El +.Pp +The range check is important than the unconverted characters check, +and it is performed first. +If a program needs to know if there were unconverted characters when an +out of range number has been provided, it needs to supply and test +.Fa endptr. .Sh SEE ALSO .Xr atof 3 , .Xr atoi 3 , Index: src/lib/libc/stdlib/strtou.3 diff -u src/lib/libc/stdlib/strtou.3:1.7 src/lib/libc/stdlib/strtou.3:1.8 --- src/lib/libc/stdlib/strtou.3:1.7 Mon Jul 3 17:32:50 2017 +++ src/lib/libc/stdlib/strtou.3 Sat Jan 20 11:13:39 2024 @@ -1,4 +1,4 @@ -.\" $NetBSD: strtou.3,v 1.7 2017/07/03 21:32:50 wiz Exp $ +.\" $NetBSD: strtou.3,v 1.8 2024/01/20 16:13:39 christos Exp $ .\" .\" Copyright (c) 1990, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -36,12 +36,12 @@ .\" Created by Kamil Rytarowski, based on ID: .\" NetBSD: strtoul.3,v 1.29 2015/03/10 13:00:58 christos Exp .\" -.Dd November 13, 2015 +.Dd January 20, 2024 .Dt STRTOU 3 .Os .Sh NAME .Nm strtou -.Nd convert a string to an uintmax_t integer +.Nd convert a string value to an uintmax_t integer .Sh LIBRARY .Lb libc .Sh SYNOPSIS @@ -120,7 +120,7 @@ The remainder of the string is converted .Em uintmax_t value in the obvious manner, stopping at the end of the string -or at the first character that does not produce a valid digit +or at the first character which is not a valid digit in the given base. (In bases above 10, the letter .Ql A @@ -195,12 +195,18 @@ In this case, .Fa endptr points to the first unconverted character. .It Bq Er ERANGE -The given string was out of range; the value converted has been clamped; or -the range given was invalid, i.e. +The given string was out of range; the value converted has been clamped; +or the range given was invalid, i.e. .Fa lo > .Fa hi . .El +.Pp +The range check is important than the unconverted characters check, +and it is performed first. +If a program needs to know if there were unconverted characters when an +out of range number has been provided, it needs to supply and test +.Fa endptr. .Sh SEE ALSO .Xr atof 3 , .Xr atoi 3 , Index: src/lib/libc/stdlib/strtonum.c diff -u src/lib/libc/stdlib/strtonum.c:1.6 src/lib/libc/stdlib/strtonum.c:1.7 --- src/lib/libc/stdlib/strtonum.c:1.6 Thu Dec 6 01:29:56 2018 +++ src/lib/libc/stdlib/strtonum.c Sat Jan 20 11:13:39 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: strtonum.c,v 1.6 2018/12/06 06:29:56 kamil Exp $ */ +/* $NetBSD: strtonum.c,v 1.7 2024/01/20 16:13:39 christos Exp $ */ /*- * Copyright (c) 2014 The NetBSD Foundation, Inc. * All rights reserved. @@ -29,7 +29,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: strtonum.c,v 1.6 2018/12/06 06:29:56 kamil Exp $"); +__RCSID("$NetBSD: strtonum.c,v 1.7 2024/01/20 16:13:39 christos Exp $"); #include "namespace.h" @@ -46,26 +46,33 @@ strtonum(const char *nptr, long long min int e; long long rv; const char *resp; + char *eptr; if (errstr == NULL) errstr = &resp; - if (minval > maxval) { - *errstr = "invalid"; - return 0; - } + if (minval > maxval) + goto out; - rv = (long long)strtoi(nptr, NULL, 10, minval, maxval, &e); + rv = (long long)strtoi(nptr, &eptr, 10, minval, maxval, &e); - if (e == 0) { + switch (e) { + case 0: *errstr = NULL; return rv; + case ECANCELED: + case ENOTSUP: + goto out; + case ERANGE: + if (*eptr) + goto out; + *errstr = rv == maxval ? "too large" : "too small"; + return 0; + default: + abort(); } - if (e == ERANGE) - *errstr = (rv == maxval ? "too large" : "too small"); - else - *errstr = "invalid"; - +out: + *errstr = "invalid"; return 0; }