From c0567c5e1de686ae13a16d00955630b59d075948 Mon Sep 17 00:00:00 2001 From: Johnothan King Date: Thu, 27 Jan 2022 04:55:36 -0800 Subject: [PATCH] Fix spurious syntax error when using ${foo[${bar}..${baz}]} (#436) Attempting to use array subscript expansion with variables that aren't set currently causes a spurious syntax error (in ksh93u+ and older commits the reproducer crashes): $ ksh -c 'echo ${foo[${bar}..${baz}]}' # Shouldn't print anything ksh: : arithmetic syntax error src/cmd/ksh93/sh/macro.c: - Backport a parser bugfix from ksh93v- 2012-08-24 that avoids setting mp->dotdot until the copyto() function's loop is finished. src/cmd/ksh93/tests/arrays.sh: - Add regression tests for this bug. --- NEWS | 3 +++ src/cmd/ksh93/sh/macro.c | 4 +++- src/cmd/ksh93/tests/arrays.sh | 15 +++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 596742ab1..cf9f5f1b9 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,9 @@ Any uppercase BUG_* names are modernish shell bug IDs. - On Cygwin, ksh now executes scripts that do not have a #! path itself, like it does on other systems, instead of with /bin/sh. +- Fixed a spurious syntax error which occurred when attempting to use array + subscript expansion with unset variables (i.e., ${foo[${bar}..${baz}]}). + 2022-01-24: - Fixed a crashing bug in history expansion that could occur when using the "&" diff --git a/src/cmd/ksh93/sh/macro.c b/src/cmd/ksh93/sh/macro.c index eacc07623..ef529f52f 100644 --- a/src/cmd/ksh93/sh/macro.c +++ b/src/cmd/ksh93/sh/macro.c @@ -438,6 +438,7 @@ static void copyto(register Mac_t *mp,int endch, int newquote) int ansi_c = 0; int paren = 0; int ere = 0; + int dotdot = 0; int brace = 0; Sfio_t *sp = mp->sp; Stk_t *stkp = sh.stk; @@ -843,7 +844,7 @@ static void copyto(register Mac_t *mp,int endch, int newquote) { sfwrite(stkp,first,c); sfputc(stkp,0); - mp->dotdot = stktell(stkp); + dotdot = stktell(stkp); cp = first = fcseek(c+2); } break; @@ -851,6 +852,7 @@ static void copyto(register Mac_t *mp,int endch, int newquote) } done: mp->sp = sp; + mp->dotdot = dotdot; mp->quote = oldquote; } diff --git a/src/cmd/ksh93/tests/arrays.sh b/src/cmd/ksh93/tests/arrays.sh index f777068e6..c46c537bc 100755 --- a/src/cmd/ksh93/tests/arrays.sh +++ b/src/cmd/ksh93/tests/arrays.sh @@ -739,5 +739,20 @@ typeset -a foo=([1]=w [2]=x) bar=(a b c) foo+=("${bar[@]}") [[ $(typeset -p foo) == 'typeset -a foo=([1]=w [2]=x [3]=a [4]=b [5]=c)' ]] || err_exit 'Appending does not work if array contains empty indexes' +# ====== +# Array expansion should work without crashing or +# causing spurious syntax errors. +exp='b c' +got=$("$SHELL" -c ' + typeset -a ar=([0]=a [1]=b [2]=c) + integer a=1 b=2 + print ${ar[${a}..${b}]} +' 2>&1) +[[ $exp == $got ]] || err_exit $'Substituting array elements with ${ar[${a}..${b}]} doesn\'t work' \ + "(expected $(printf %q "$exp"), got $(printf %q "$got"))" +got=$("$SHELL" -c 'test -z ${foo[${bar}..${baz}]}' 2>&1) +[[ -z $got ]] || err_exit $'Using ${foo[${bar}..${baz}]} when the variable ${foo} isn\'t set fails in error' \ + "(got $(printf %q "$got"))" + # ====== exit $((Errors<125?Errors:125))