Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 10 Feb 2019 22:23:06 +0000 (UTC)
From:      Jilles Tjoelker <jilles@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r343981 - in head/bin/sh: . tests/expansion
Message-ID:  <201902102223.x1AMN6ZS089523@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jilles
Date: Sun Feb 10 22:23:05 2019
New Revision: 343981
URL: https://svnweb.freebsd.org/changeset/base/343981

Log:
  sh: Restore $((x)) error checking after fix for $((-9223372036854775808))
  
  SVN r342880 was designed to fix $((-9223372036854775808)) and things like
  $((0x8000000000000000)) but also broke error detection for values of
  variables without dollar sign ($((x))).
  
  For compatibility, overflow in plain literals continues to be ignored and
  the value is clamped to the boundary (except 9223372036854775808 which is
  changed to -9223372036854775808).
  
  Reviewed by:	se (although he would like error checking to be removed)
  MFC after:	2 weeks
  X-MFC-with:	r342880
  Differential Revision:	https://reviews.freebsd.org/D18926

Added:
  head/bin/sh/tests/expansion/arith16.0   (contents, props changed)
  head/bin/sh/tests/expansion/arith17.0   (contents, props changed)
Modified:
  head/bin/sh/arith_yacc.c
  head/bin/sh/arith_yacc.h
  head/bin/sh/arith_yylex.c
  head/bin/sh/shell.h
  head/bin/sh/tests/expansion/Makefile

Modified: head/bin/sh/arith_yacc.c
==============================================================================
--- head/bin/sh/arith_yacc.c	Sun Feb 10 21:32:39 2019	(r343980)
+++ head/bin/sh/arith_yacc.c	Sun Feb 10 22:23:05 2019	(r343981)
@@ -104,7 +104,7 @@ static arith_t arith_lookupvarint(char *varname)
 	if (str == NULL || *str == '\0')
 		str = "0";
 	errno = 0;
-	result = strtoarith_t(str, &p, 0);
+	result = strtoarith_t(str, &p);
 	if (errno != 0 || *p != '\0')
 		yyerror("variable conversion error");
 	return result;

Modified: head/bin/sh/arith_yacc.h
==============================================================================
--- head/bin/sh/arith_yacc.h	Sun Feb 10 21:32:39 2019	(r343980)
+++ head/bin/sh/arith_yacc.h	Sun Feb 10 22:23:05 2019	(r343981)
@@ -90,4 +90,5 @@ union yystype {
 
 extern union yystype yylval;
 
+arith_t strtoarith_t(const char *restrict nptr, char **restrict endptr);
 int yylex(void);

Modified: head/bin/sh/arith_yylex.c
==============================================================================
--- head/bin/sh/arith_yylex.c	Sun Feb 10 21:32:39 2019	(r343980)
+++ head/bin/sh/arith_yylex.c	Sun Feb 10 22:23:05 2019	(r343981)
@@ -35,6 +35,8 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include <ctype.h>
+#include <errno.h>
 #include <inttypes.h>
 #include <stdlib.h>
 #include <string.h>
@@ -50,6 +52,32 @@ __FBSDID("$FreeBSD$");
 #error Arithmetic tokens are out of order.
 #endif
 
+arith_t
+strtoarith_t(const char *restrict nptr, char **restrict endptr)
+{
+	arith_t val;
+
+	while (isspace((unsigned char)*nptr))
+		nptr++;
+	switch (*nptr) {
+		case '-':
+			return strtoimax(nptr, endptr, 0);
+		case '0':
+			return (arith_t)strtoumax(nptr, endptr, 0);
+		default:
+			val = (arith_t)strtoumax(nptr, endptr, 0);
+			if (val >= 0)
+				return val;
+			else if (val == ARITH_MIN) {
+				errno = ERANGE;
+				return ARITH_MIN;
+			} else {
+				errno = ERANGE;
+				return ARITH_MAX;
+			}
+	}
+}
+
 int
 yylex(void)
 {
@@ -78,7 +106,7 @@ yylex(void)
 		case '7':
 		case '8':
 		case '9':
-			yylval.val = strtoarith_t(buf, &end, 0);
+			yylval.val = strtoarith_t(buf, &end);
 			arith_buf = end;
 			return ARITH_NUM;
 		case 'A':

Modified: head/bin/sh/shell.h
==============================================================================
--- head/bin/sh/shell.h	Sun Feb 10 21:32:39 2019	(r343980)
+++ head/bin/sh/shell.h	Sun Feb 10 22:23:05 2019	(r343981)
@@ -59,7 +59,6 @@
  */
 typedef intmax_t arith_t;
 #define	ARITH_FORMAT_STR  "%" PRIdMAX
-#define	strtoarith_t(nptr, endptr, base)  (intmax_t)strtoumax(nptr, endptr, base)
 #define	ARITH_MIN INTMAX_MIN
 #define	ARITH_MAX INTMAX_MAX
 

Modified: head/bin/sh/tests/expansion/Makefile
==============================================================================
--- head/bin/sh/tests/expansion/Makefile	Sun Feb 10 21:32:39 2019	(r343980)
+++ head/bin/sh/tests/expansion/Makefile	Sun Feb 10 22:23:05 2019	(r343981)
@@ -22,6 +22,8 @@ ${PACKAGE}FILES+=	arith12.0
 ${PACKAGE}FILES+=	arith13.0
 ${PACKAGE}FILES+=	arith14.0
 ${PACKAGE}FILES+=	arith15.0
+${PACKAGE}FILES+=	arith16.0
+${PACKAGE}FILES+=	arith17.0
 ${PACKAGE}FILES+=	assign1.0
 ${PACKAGE}FILES+=	cmdsubst1.0
 ${PACKAGE}FILES+=	cmdsubst2.0

Added: head/bin/sh/tests/expansion/arith16.0
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/bin/sh/tests/expansion/arith16.0	Sun Feb 10 22:23:05 2019	(r343981)
@@ -0,0 +1,26 @@
+# $FreeBSD$
+
+failures=0
+
+for x in \
+	0x10000000000000000 \
+	-0x8000000000000001 \
+	0xfffffffffffffffffffffffffffffffff \
+	-0xfffffffffffffffffffffffffffffffff \
+	02000000000000000000000 \
+	9223372036854775808 \
+	9223372036854775809 \
+	-9223372036854775809 \
+	9999999999999999999999999 \
+	-9999999999999999999999999
+do
+	msg=$({
+		v=$((x)) || :
+	} 3>&1 >&2 2>&3 3>&-)
+	r=$?
+	if [ "$r" = 0 ] || [ -z "$msg" ]; then
+		printf 'Failed: %s\n' "$x"
+		: $((failures += 1))
+	fi
+done
+exit $((failures > 0))

Added: head/bin/sh/tests/expansion/arith17.0
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/bin/sh/tests/expansion/arith17.0	Sun Feb 10 22:23:05 2019	(r343981)
@@ -0,0 +1,3 @@
+# $FreeBSD$
+
+[ $((9223372036854775809)) -gt 0 ]



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201902102223.x1AMN6ZS089523>