changeset 672:0dd0932ec440

int: fail all str2uXX calls with -ERANGE on negative looking input We have to manually check for negative looking input since (1) negative numbers cannot be represented with uintXX_t types, and (2) strtoull doesn't fail (instead it does 2's complement negation of the unsigned bits). We don't bother differentiating between input consisting of a negative but otherwise valid number and a non-numeric string starting with a dash. Ideally, we'd return -ERANGE for the former and -EINVAL for the latter, but it isn't worth the additional clock cycles to differentiate between the two. Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Thu, 21 Feb 2019 19:13:41 -0500
parents f3c75c3d7a04
children 927cbe0ea334
files include/jeffpc/int.h tests/test_str2uint.c
diffstat 2 files changed, 65 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/include/jeffpc/int.h	Thu Feb 21 18:44:13 2019 -0500
+++ b/include/jeffpc/int.h	Thu Feb 21 19:13:41 2019 -0500
@@ -46,6 +46,14 @@
 									\
 	*i = 0;								\
 									\
+	/*								\
+	 * negative numbers aren't representable by uintXX_t; this may	\
+	 * mask a -EINVAL if the input is of the form:			\
+	 * "-<some non-number>"						\
+	 */								\
+	if (*s == '-')							\
+		return -ERANGE;						\
+									\
 	errno = 0;							\
 	tmp = strtoull(s, &endptr, base);				\
 									\
--- a/tests/test_str2uint.c	Thu Feb 21 18:44:13 2019 -0500
+++ b/tests/test_str2uint.c	Thu Feb 21 19:13:41 2019 -0500
@@ -143,9 +143,65 @@
 		.out[B16] = ENT(0xa, 0xa, 0xa, 0, 0, 0),
 	},
 	/*
+	 * Check negative numbers
+	 */
+	{
+		.in       = "-0",
+		.out[B8]  = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE),
+		.out[B10] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE),
+		.out[B16] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE),
+	},
+	{
+		.in       = "-1",
+		.out[B8]  = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE),
+		.out[B10] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE),
+		.out[B16] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE),
+	},
+	{
+		.in       = "-8",
+		.out[B8]  = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE),
+		.out[B10] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE),
+		.out[B16] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE),
+	},
+	{
+		.in	  = "-A",
+		.out[B8]  = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE),
+		.out[B10] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE),
+		.out[B16] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE),
+	},
+	{
+		.in	  = "-a",
+		.out[B8]  = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE),
+		.out[B10] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE),
+		.out[B16] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE),
+	},
+	{
+		.in	  = "-0XA",
+		.out[B8]  = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE),
+		.out[B10] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE),
+		.out[B16] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE),
+	},
+	{
+		.in	  = "-0Xa",
+		.out[B8]  = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE),
+		.out[B10] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE),
+		.out[B16] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE),
+	},
+	{
+		.in	  = "-0xA",
+		.out[B8]  = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE),
+		.out[B10] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE),
+		.out[B16] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE),
+	},
+	{
+		.in	  = "-0xa",
+		.out[B8]  = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE),
+		.out[B10] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE),
+		.out[B16] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE),
+	},
+	/*
 	 * FIXME: more test cases
 	 *   - check values > max for type
-	 *   - check inputs starting with '-' ?
 	 *   - check inputs with leading garbage
 	 *   - check inputs with trailing garbage
 	 */