Module Name: src Committed By: christos Date: Sun Jul 21 17:40:42 UTC 2024
Modified Files: src/common/lib/libc/stdlib: _strtoi.h Log Message: POSIX allows systems that report EINVAL when no digits are found. On such systems the only way to differentiate EINVAL and ECANCELED is to initialized the end pointer to NULL before the call. On EINVAL cases, strto*max(3) will leave the pointer unmodified, so we'll read back the original NULL. On ECANCELED cases, strto*max(3) will set it to nptr. This also prevents UB read of endptr on an unsupported base argument. (Alejandro Colomar) To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 src/common/lib/libc/stdlib/_strtoi.h 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.3 src/common/lib/libc/stdlib/_strtoi.h:1.4 --- src/common/lib/libc/stdlib/_strtoi.h:1.3 Sat Jan 20 11:13:39 2024 +++ src/common/lib/libc/stdlib/_strtoi.h Sun Jul 21 13:40:42 2024 @@ -1,8 +1,9 @@ -/* $NetBSD: _strtoi.h,v 1.3 2024/01/20 16:13:39 christos Exp $ */ +/* $NetBSD: _strtoi.h,v 1.4 2024/07/21 17:40:42 christos Exp $ */ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. + * Copyright (c) 2024, Alejandro Colomar <a...@kernel.org> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -69,7 +70,7 @@ INT_FUNCNAME(_int_, _FUNCNAME, _l)(const int serrno; #endif __TYPE im; - char *ep; + char *e; int rep; _DIAGASSERT(hi >= lo); @@ -77,8 +78,7 @@ INT_FUNCNAME(_int_, _FUNCNAME, _l)(const _DIAGASSERT(nptr != NULL); /* endptr may be NULL */ - if (endptr == NULL) - endptr = &ep; + e = NULL; if (rstatus == NULL) rstatus = &rep; @@ -90,9 +90,9 @@ INT_FUNCNAME(_int_, _FUNCNAME, _l)(const #if defined(_KERNEL) || defined(_STANDALONE) || \ defined(HAVE_NBTOOL_CONFIG_H) || defined(BCS_ONLY) - im = __WRAPPED(nptr, endptr, base); + im = __WRAPPED(nptr, &e, base); #else - im = __WRAPPED_L(nptr, endptr, base, loc); + im = __WRAPPED_L(nptr, &e, base, loc); #endif #if !defined(_KERNEL) && !defined(_STANDALONE) @@ -100,8 +100,11 @@ INT_FUNCNAME(_int_, _FUNCNAME, _l)(const errno = serrno; #endif + if (endptr != NULL && e != NULL) + *endptr = e; + /* No digits were found */ - if (*rstatus == 0 && nptr == *endptr) + if (nptr == e && (*rstatus == 0 || *rstatus == EINVAL)) *rstatus = ECANCELED; if (im < lo) { @@ -117,7 +120,7 @@ INT_FUNCNAME(_int_, _FUNCNAME, _l)(const } /* There are further characters after number */ - if (*rstatus == 0 && **endptr != '\0') + if (*rstatus == 0 && *e != '\0') *rstatus = ENOTSUP; return im;