diff --git a/man/strtoi.3bsd b/man/strtoi.3bsd index 15102da..5988361 100644 --- a/man/strtoi.3bsd +++ b/man/strtoi.3bsd @@ -1,4 +1,4 @@ -.\" $NetBSD: strtoi.3,v 1.7 2017/07/03 21:32:50 wiz Exp $ +.\" $NetBSD: strtoi.3,v 1.10 2024/02/10 18:43:51 andvar 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 3bsd .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 .ds str-Lb-libbsd Utility functions from BSD systems (libbsd, \-lbsd) .ds doc-str-Lb-libbsd \*[str-Lb-libbsd] @@ -63,8 +63,7 @@ for include usage.) .Sh DESCRIPTION The .Fn strtoi -function -converts the string in +function converts the string in .Fa nptr to an .Ft intmax_t @@ -77,7 +76,7 @@ and ensures that the result is always in the range [ .Fa lo .. .Fa hi ]. -In adddition it always places +In addition it always places .Dv 0 on success or a conversion status in the .Fa rstatus @@ -122,10 +121,11 @@ is taken as 10 (decimal) unless the next character is .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 @@ -206,6 +206,12 @@ or the range given was invalid, i.e. > .Fa hi . .El +.Pp +The range check is more 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 , diff --git a/man/strtou.3bsd b/man/strtou.3bsd index d7e02eb..0291568 100644 --- a/man/strtou.3bsd +++ b/man/strtou.3bsd @@ -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 3bsd .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 .ds str-Lb-libbsd Utility functions from BSD systems (libbsd, \-lbsd) .ds doc-str-Lb-libbsd \*[str-Lb-libbsd] @@ -76,7 +76,7 @@ and ensures that the result is always in the range [ .Fa lo .. .Fa hi ]. -In adddition it always places +In addition it always places .Dv 0 on success or a conversion status in the .Fa rstatus @@ -125,7 +125,7 @@ The remainder of the string is converted to an .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 @@ -200,12 +200,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 more 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 , @@ -220,13 +226,13 @@ the range given was invalid, i.e. .Xr strtoull 3 , .Xr strtoumax 3 .Sh STANDARDS -.ds doc-operating-system-NetBSD-7.0 7.0 The .Fn strtou function is a .Nx extension. .Sh HISTORY +.ds doc-operating-system-NetBSD-7.0 7.0 The .Fn strtou function first appeared in diff --git a/src/strtoi.c b/src/strtoi.c index 9e3771d..7a27ca7 100644 --- a/src/strtoi.c +++ b/src/strtoi.c @@ -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 @@ -32,7 +32,7 @@ * NetBSD: src/lib/libc/locale/_wcstoul.h,v 1.2 2003/08/07 16:43:03 agc Exp * * Created by Kamil Rytarowski, based on ID: - * NetBSD: src/common/lib/libc/stdlib/_strtoul.h,v 1.7 2013/05/17 12:55:56 joe… + * NetBSD: src/common/lib/libc/stdlib/_strtoul.h,v 1.7 2013/05/17 12:55:56 joerg Exp */ #include @@ -73,25 +73,25 @@ strtoi(const char *__restrict nptr, *rstatus = errno; errno = serrno; - 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; } diff --git a/src/strtonum.c b/src/strtonum.c index 2fa0fcf..8d6faa1 100644 --- a/src/strtonum.c +++ b/src/strtonum.c @@ -1,4 +1,4 @@ -/* $NetBSD: strtonum.c,v 1.5 2018/01/04 20:57:29 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. @@ -42,21 +42,33 @@ strtonum(const char *nptr, long long minval, long long maxval, int e; long long rv; const char *resp; + char *eptr; if (errstr == NULL) errstr = &resp; - rv = (long long)strtoi(nptr, NULL, 10, minval, maxval, &e); + if (minval > maxval) + goto out; - if (e == 0) { + rv = (long long)strtoi(nptr, &eptr, 10, minval, maxval, &e); + + 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; } diff --git a/src/strtou.c b/src/strtou.c index 0e22a88..a87adcc 100644 --- a/src/strtou.c +++ b/src/strtou.c @@ -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 @@ -73,25 +73,25 @@ strtou(const char *__restrict nptr, *rstatus = errno; errno = serrno; - 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; }