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;

Reply via email to