mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Reset arithmetic recursion level on all errors (re: 264ba48b)
The recursion level for arithmetic expressions is kept track of in
a static 'level' variable in streval.c. It is reset when arithmetic
expressions throw an error.
But an error for an arithmetic expression may also occur elsewhere
-- at least in one case: when an arithmetic expression attempts to
change a read-only variable. In that case, the recursion level is
never reset because that code does not have access to the static
'level' variable.
If many such conditions occur (as in the new readonly.sh regression
tests), an arithmetic command like 'i++' may eventually fail with a
'recursion too deep' error.
To mitigate the problem, MAXLEVEL in streval.c was changed from 9
to 1024 in 264ba48b (as in the ksh 93v- beta). This commit leaves
that increase, but adds a proper fix.
src/cmd/ksh93/include/defs.h:
- Add global sh.arithrecursion (a.k.a. shp->arithrecursion)
variable to keep track of the arithmetic recursion level,
replacing the static 'level' variable in streval.c.
src/cmd/ksh93/sh/xec.c: sh_exec():
- Reset sh.arithrecursion before starting a new simple command
(TCOM), a new subshell with parentheses (TPAR), a new pipe
(TFIL), or a new [[ ... ]] command (TTST). These are the same
places where 'echeck' is set to 1 for --errexit and ERR trap
checks, so it should cover everything.
src/cmd/ksh93/sh/streval.c:
- Change all uses of 'level' to sh.arithrecursion.
- _seterror, aritherror(): No longer bother to reset the level
to zero here; xec.c should have this covered for all cases now.
src/cmd/ksh93/tests/arith.sh:
- Add tests for main shell and subshell.
This commit is contained in:
parent
f6bc5c03ca
commit
d50d3d7c4c
6 changed files with 43 additions and 10 deletions
|
|
@ -822,5 +822,31 @@ got=$(set +x; { var="x\]+b\[\$(echo INJECTION >&2)"; typeset -A a; ((a[\$var]++)
|
|||
got=$(set +x; { var="x\]+b\[\$(uname>&2)"; typeset -A a; ((a["\$var"]++)); typeset -p a; } 2>&1)
|
||||
[[ $got == "$exp" ]] || err_exit "Array subscript quoting test 5M: expected $(printf %q "$exp"), got $(printf %q "$got")"
|
||||
|
||||
# ======
|
||||
# Arithmetic recursion level was not reset on encountering readonly error in combination with a recursive arithmetic expression.
|
||||
# (arithmetic array subscripts inside arithmetic expressions are one example of such recursion)
|
||||
# https://github.com/ksh93/ksh/pull/239#discussion_r606874442
|
||||
srcdir=${SHTESTS_COMMON%/tests/*}
|
||||
integer maxlevel=$(grep $'^#define MAXLEVEL\t' "$srcdir/sh/streval.c" | sed 's/.*MAXLEVEL//')
|
||||
if ((!maxlevel))
|
||||
then err_exit "could not get maximum arithmetic recursion level from source code; update this test"
|
||||
maxlevel=1024
|
||||
fi
|
||||
integer loopcount=maxlevel+10
|
||||
got=$(
|
||||
typeset -r -A -i ro_arr=([a]=10 [b]=20 [c]=30)
|
||||
for ((i=0; i<loopcount; i++)); do
|
||||
let "ro_arr[i+1] += 5"
|
||||
done 2>&1
|
||||
)
|
||||
[[ $got == *recursion* ]] && err_exit "recursion level not reset on readonly error (main shell)"
|
||||
got=$(
|
||||
typeset -r -A -i ro_arr=([a]=10 [b]=20 [c]=30)
|
||||
for ((i=0; i<loopcount; i++)); do
|
||||
( ((ro_arr[i+1] += 5)) )
|
||||
done 2>&1
|
||||
)
|
||||
[[ $got == *recursion* ]] && err_exit "recursion level not reset on readonly error (subshell)"
|
||||
|
||||
# ======
|
||||
exit $((Errors<125?Errors:125))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue