Commit 6f68c930765d95ab2644c7a1210a0a640fd9d4bf

Guillem Jover 2018-05-21T00:22:38

Switch strtonum() implementation from strtoll() to strtoi() Import from NetBSD.

diff --git a/COPYING b/COPYING
index 10fb229..e197193 100644
--- a/COPYING
+++ b/COPYING
@@ -274,8 +274,10 @@ Files:
  src/fmtcheck.c
  src/humanize_number.c
  src/stringlist.c
+ src/strtonum.c
 Copyright:
- Copyright © 1994, 1997-2000, 2002, 2008, 2010 The NetBSD Foundation, Inc.
+ Copyright © 1994, 1997-2000, 2002, 2008, 2010, 2014
+     The NetBSD Foundation, Inc.
  Copyright © 2013 John-Mark Gurney <jmg@FreeBSD.org>
  All rights reserved.
  .
@@ -459,7 +461,6 @@ Files:
  src/reallocarray.c
  src/strlcat.c
  src/strlcpy.c
- src/strtonum.c
 Copyright:
  Copyright © 2004 Ted Unangst and Todd Miller
  All rights reserved.
diff --git a/man/strtonum.3bsd b/man/strtonum.3bsd
index fd34ad6..7d82fc8 100644
--- a/man/strtonum.3bsd
+++ b/man/strtonum.3bsd
@@ -1,3 +1,6 @@
+.\" $NetBSD: strtonum.3,v 1.2 2015/01/19 11:47:41 wiz Exp $
+.\" $OpenBSD: strtonum.3,v 1.17 2013/08/14 06:32:28 jmc Exp $
+.\"
 .\" Copyright (c) 2004 Ted Unangst
 .\"
 .\" Permission to use, copy, modify, and distribute this software for any
@@ -12,10 +15,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.\" $OpenBSD: strtonum.3,v 1.12 2005/10/26 11:37:58 jmc Exp $
-.\" $FreeBSD$
-.\"
-.Dd April 29, 2004
+.Dd January 18, 2015
 .Dt STRTONUM 3bsd
 .Os
 .Sh NAME
@@ -45,14 +45,6 @@ function converts the string in
 to a
 .Vt "long long"
 value.
-The
-.Fn strtonum
-function was designed to facilitate safe, robust programming
-and overcome the shortcomings of the
-.Xr atoi 3
-and
-.Xr strtol 3
-family of interfaces.
 .Pp
 The string may begin with an arbitrary amount of whitespace
 (as determined by
@@ -112,15 +104,13 @@ The above example will guarantee that the value of iterations is between
 1 and 64 (inclusive).
 .Sh ERRORS
 .Bl -tag -width Er
-.It Bq Er ERANGE
-The given string was out of range.
 .It Bq Er EINVAL
-The given string did not consist solely of digit characters.
-.It Bq Er EINVAL
-The supplied
-.Fa minval
+The given string did not consist solely of digit characters; or
+.Ar minval
 was larger than
-.Fa maxval .
+.Ar maxval .
+.It Bq Er ERANGE
+The given string was out of range.
 .El
 .Pp
 If an error occurs,
@@ -142,21 +132,58 @@ The string did not consist solely of digit characters.
 .Xr atoll 3 ,
 .Xr sscanf 3 ,
 .Xr strtod 3 ,
+.Xr strtoi 3bsd ,
 .Xr strtol 3 ,
-.Xr strtoul 3
+.Xr strtoll 3 ,
+.Xr strtou 3bsd ,
+.Xr strtoul 3 ,
+.Xr strtoull 3
 .Sh STANDARDS
-The
 .Fn strtonum
-function is a
-.Bx
+is an
+.Ox
 extension.
-The existing alternatives, such as
-.Xr atoi 3
-and
-.Xr strtol 3 ,
-are either impossible or difficult to use safely.
 .Sh HISTORY
 The
 .Fn strtonum
 function first appeared in
 .Ox 3.6 .
+.Fn strtonum
+was redesigned in
+.Nx 8
+as
+.Fn strtoi 3bsd
+and
+.Fn strtou 3bsd .
+.Sh CAVEATS
+The
+.Fn strtonum
+function was designed to facilitate safe,
+robust programming and overcome the shortcomings of the
+.Xr atoi 3
+and
+.Xr strtol 3
+family of interfaces, however there are problems with the
+.Fn strtonum
+API:
+.Bl -dash
+.It
+will return 0 on failure; 0 might not be in range, so that necessitates
+an error check even if you want to avoid it
+.It
+does not differentiate 'illegal' returns, so we can't tell the
+difference between partial and no conversions
+.It
+returns english strings
+.It
+can't set the base, or find where the conversion ended
+.It
+hardcodes long long integer type
+.El
+To overcome the shortcomings of
+.Fn strtonum
+.Nx
+provides
+.Fn strtou 3bsd
+and
+.Fn strtoi 3bsd .
diff --git a/src/strtonum.c b/src/strtonum.c
index 1c722ab..2fa0fcf 100644
--- a/src/strtonum.c
+++ b/src/strtonum.c
@@ -1,67 +1,62 @@
+/*	$NetBSD: strtonum.c,v 1.5 2018/01/04 20:57:29 kamil Exp $	*/
 /*-
- * Copyright (c) 2004 Ted Unangst and Todd Miller
+ * Copyright (c) 2014 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
  *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
  *
- *	$OpenBSD: strtonum.c,v 1.6 2004/08/03 19:38:01 millert Exp $
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include <sys/cdefs.h>
 
-#include <errno.h>
-#include <limits.h>
+#include <stdio.h>
 #include <stdlib.h>
-
-#define INVALID 	1
-#define TOOSMALL 	2
-#define TOOLARGE 	3
+#include <errno.h>
+#include <inttypes.h>
 
 long long
-strtonum(const char *numstr, long long minval, long long maxval,
-    const char **errstrp)
+strtonum(const char *nptr, long long minval, long long maxval,
+         const char **errstr)
 {
-	long long ll = 0;
-	char *ep;
-	int error = 0;
-	struct errval {
-		const char *errstr;
-		int err;
-	} ev[4] = {
-		{ NULL,		0 },
-		{ "invalid",	EINVAL },
-		{ "too small",	ERANGE },
-		{ "too large",	ERANGE },
-	};
+	int e;
+	long long rv;
+	const char *resp;
 
-	ev[0].err = errno;
-	errno = 0;
-	if (minval > maxval)
-		error = INVALID;
-	else {
-		ll = strtoll(numstr, &ep, 10);
-		if (errno == EINVAL || numstr == ep || *ep != '\0')
-			error = INVALID;
-		else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
-			error = TOOSMALL;
-		else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
-			error = TOOLARGE;
+	if (errstr == NULL)
+		errstr = &resp;
+
+	rv = (long long)strtoi(nptr, NULL, 10, minval, maxval, &e);
+
+	if (e == 0) {
+		*errstr = NULL;
+		return rv;
 	}
-	if (errstrp != NULL)
-		*errstrp = ev[error].errstr;
-	errno = ev[error].err;
-	if (error)
-		ll = 0;
 
-	return (ll);
+	if (e == ERANGE)
+		*errstr = (rv == maxval ? "too large" : "too small");
+	else
+		*errstr = "invalid";
+
+	return 0;
 }