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:
parent
2a0f9d5416
commit
aac5464b61
@ -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;
|
||||
|
@ -90,4 +90,5 @@ union yystype {
|
||||
|
||||
extern union yystype yylval;
|
||||
|
||||
arith_t strtoarith_t(const char *restrict nptr, char **restrict endptr);
|
||||
int yylex(void);
|
||||
|
@ -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':
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
26
bin/sh/tests/expansion/arith16.0
Normal file
26
bin/sh/tests/expansion/arith16.0
Normal file
@ -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))
|
3
bin/sh/tests/expansion/arith17.0
Normal file
3
bin/sh/tests/expansion/arith17.0
Normal file
@ -0,0 +1,3 @@
|
||||
# $FreeBSD$
|
||||
|
||||
[ $((9223372036854775809)) -gt 0 ]
|
Loading…
Reference in New Issue
Block a user