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 <[email protected]>
*
* 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;