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
This commit is contained in:
+1
-1
@@ -104,7 +104,7 @@ static arith_t arith_lookupvarint(char *varname)
|
|||||||
if (str == NULL || *str == '\0')
|
if (str == NULL || *str == '\0')
|
||||||
str = "0";
|
str = "0";
|
||||||
errno = 0;
|
errno = 0;
|
||||||
result = strtoarith_t(str, &p, 0);
|
result = strtoarith_t(str, &p);
|
||||||
if (errno != 0 || *p != '\0')
|
if (errno != 0 || *p != '\0')
|
||||||
yyerror("variable conversion error");
|
yyerror("variable conversion error");
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -90,4 +90,5 @@ union yystype {
|
|||||||
|
|
||||||
extern union yystype yylval;
|
extern union yystype yylval;
|
||||||
|
|
||||||
|
arith_t strtoarith_t(const char *restrict nptr, char **restrict endptr);
|
||||||
int yylex(void);
|
int yylex(void);
|
||||||
|
|||||||
+29
-1
@@ -35,6 +35,8 @@
|
|||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__FBSDID("$FreeBSD$");
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -50,6 +52,32 @@ __FBSDID("$FreeBSD$");
|
|||||||
#error Arithmetic tokens are out of order.
|
#error Arithmetic tokens are out of order.
|
||||||
#endif
|
#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
|
int
|
||||||
yylex(void)
|
yylex(void)
|
||||||
{
|
{
|
||||||
@@ -78,7 +106,7 @@ yylex(void)
|
|||||||
case '7':
|
case '7':
|
||||||
case '8':
|
case '8':
|
||||||
case '9':
|
case '9':
|
||||||
yylval.val = strtoarith_t(buf, &end, 0);
|
yylval.val = strtoarith_t(buf, &end);
|
||||||
arith_buf = end;
|
arith_buf = end;
|
||||||
return ARITH_NUM;
|
return ARITH_NUM;
|
||||||
case 'A':
|
case 'A':
|
||||||
|
|||||||
@@ -59,7 +59,6 @@
|
|||||||
*/
|
*/
|
||||||
typedef intmax_t arith_t;
|
typedef intmax_t arith_t;
|
||||||
#define ARITH_FORMAT_STR "%" PRIdMAX
|
#define ARITH_FORMAT_STR "%" PRIdMAX
|
||||||
#define strtoarith_t(nptr, endptr, base) (intmax_t)strtoumax(nptr, endptr, base)
|
|
||||||
#define ARITH_MIN INTMAX_MIN
|
#define ARITH_MIN INTMAX_MIN
|
||||||
#define ARITH_MAX INTMAX_MAX
|
#define ARITH_MAX INTMAX_MAX
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ ${PACKAGE}FILES+= arith12.0
|
|||||||
${PACKAGE}FILES+= arith13.0
|
${PACKAGE}FILES+= arith13.0
|
||||||
${PACKAGE}FILES+= arith14.0
|
${PACKAGE}FILES+= arith14.0
|
||||||
${PACKAGE}FILES+= arith15.0
|
${PACKAGE}FILES+= arith15.0
|
||||||
|
${PACKAGE}FILES+= arith16.0
|
||||||
|
${PACKAGE}FILES+= arith17.0
|
||||||
${PACKAGE}FILES+= assign1.0
|
${PACKAGE}FILES+= assign1.0
|
||||||
${PACKAGE}FILES+= cmdsubst1.0
|
${PACKAGE}FILES+= cmdsubst1.0
|
||||||
${PACKAGE}FILES+= cmdsubst2.0
|
${PACKAGE}FILES+= cmdsubst2.0
|
||||||
|
|||||||
@@ -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))
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# $FreeBSD$
|
||||||
|
|
||||||
|
[ $((9223372036854775809)) -gt 0 ]
|
||||||
Reference in New Issue
Block a user