From 655c4be1c1c4279b96a4af32c7ca704b06c21c74 Mon Sep 17 00:00:00 2001 From: hyenias <58673227+hyenias@users.noreply.github.com> Date: Tue, 4 May 2021 22:29:19 -0400 Subject: [PATCH] Correct regression for compound arithmetic expressions (re: 642a1053) (#297) I did not realize that lvalue->nosub and lvalue->sub variables are not reset when another assignment occurs later down the line. Example: (( arr[0][1]+=1, arr[2]=7 )) src/cmd/ksh93/sh/arith.c: arith(): - For assignment operations, reset lvalue's nosub and sub variables so the target for the next assignment is not redirected. src/cmd/ksh93/tests/arrays2.sh: - Add in a few regression tests that utilize compound arithmetic expressions having at least an assignment operation (+=) followed by a normal assignment (=). --- src/cmd/ksh93/sh/arith.c | 5 ++++- src/cmd/ksh93/tests/arrays2.sh | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/cmd/ksh93/sh/arith.c b/src/cmd/ksh93/sh/arith.c index 603876c06..214575de4 100644 --- a/src/cmd/ksh93/sh/arith.c +++ b/src/cmd/ksh93/sh/arith.c @@ -234,10 +234,13 @@ static Sfdouble_t arith(const char **ptr, struct lval *lvalue, int type, Sfdoubl case ASSIGN: { register Namval_t *np; - if (lvalue->nosub > 0 && lvalue->sub) /* indexed array ARITH_ASSIGNOP */ + if (lvalue->sub && lvalue->nosub > 0) /* indexed array ARITH_ASSIGNOP */ { np = (Namval_t*)lvalue->sub; /* use saved subscript reference instead of last worked value */ nv_putsub(np, NIL(char*), lvalue->nosub-1); + /* reset nosub and sub for next assignment in a compound arithmetic expression */ + lvalue->nosub = 0; + lvalue->sub = 0; } else { diff --git a/src/cmd/ksh93/tests/arrays2.sh b/src/cmd/ksh93/tests/arrays2.sh index 2f7fda3bd..6b273d66e 100755 --- a/src/cmd/ksh93/tests/arrays2.sh +++ b/src/cmd/ksh93/tests/arrays2.sh @@ -256,6 +256,9 @@ ini() { unset arr; typeset -a arr=((10 20) 6 8); } [[ $( ini; ((arr[2]+=arr[0][0])); typeset -p arr) == 'typeset -a arr=((10 20) 6 18)' ]] || err_exit 'ASSIGNOP: arr[2]+=arr[0][0] failed.' [[ $( ini; ((arr[2]+=arr[0][1])); typeset -p arr) == 'typeset -a arr=((10 20) 6 28)' ]] || err_exit 'ASSIGNOP: arr[2]+=arr[0][1] failed.' [[ $( ini; ((arr[3]+=arr[0][1])); typeset -p arr) == 'typeset -a arr=((10 20) 6 8 20)' ]] || err_exit 'ASSIGNOP: arr[2]+=arr[0][1] failed.' +[[ $( ini; ((arr[0][1]+=arr[1]+13, arr[2]=42)); typeset -p arr) == 'typeset -a arr=((10 39) 6 42)' ]] || err_exit 'ASSIGNOPs: (_+=,_=_) failed.' +[[ $( ini; (( (arr[0][1]*=arr[2]) ? arr[0][1]+=arr[1] : arr[1]=7)); typeset -p arr) == 'typeset -a arr=((10 166) 6 8)' ]] || err_exit 'ASSIGNOPs: (_*=_)?_:_ true failed.' +[[ $( ini; (( (arr[0][2]*=arr[2]) ? arr[0][1]+=arr[1] : arr[1]=7)); typeset -p arr) == 'typeset -a arr=((10 20 0) 7 8)' ]] || err_exit 'ASSIGNOPs: (_*=_)?_:_ false failed.' unset arr unset -f ini