sh: Correctly handle positional parameters beyond INT_MAX on 64-bit systems.

Currently, there can be no more than INT_MAX positional parameters. Make
sure to treat all higher ones as unset to avoid incorrect results and
crashes.

On 64-bit systems, our atoi() takes the low 32 bits of the strtol() and
sign-extends them.

On 32-bit systems, the call to atoi() returned INT_MAX for too high values
and there is not enough address space for so many positional parameters, so
there was no issue.
This commit is contained in:
Jilles Tjoelker 2014-07-12 21:54:11 +00:00
parent 3551142804
commit 7b9104c0a9
3 changed files with 19 additions and 2 deletions

View File

@ -846,9 +846,11 @@ varisset(const char *name, int nulok)
}
} else if (is_digit(*name)) {
char *ap;
int num = atoi(name);
long num;
if (num > shellparam.nparam)
errno = 0;
num = strtol(name, NULL, 10);
if (errno != 0 || num > shellparam.nparam)
return 0;
if (num == 0)

View File

@ -15,6 +15,7 @@ FILES+= positional1.0
FILES+= positional2.0
FILES+= positional3.0
FILES+= positional4.0
FILES+= positional5.0
FILES+= pwd1.0
FILES+= pwd2.0

View File

@ -0,0 +1,14 @@
# $FreeBSD$
i=1
r=0
while [ $i -lt $((0x100000000)) ]; do
t=
eval t=\${$i-x}
case $t in
x) ;;
*) echo "Problem with \${$i}" >&2; r=1 ;;
esac
i=$((i + 0x10000000))
done
exit $r