Skip to content

Commit

Permalink
Fix spurious syntax error in multidim. indexed array assignments
Browse files Browse the repository at this point in the history
Example reproducers:
  $ my_array=((somevalue) (select)) && typeset -p my_array
  -ksh: syntax error: `select' unexpected
  $ my_array=((somevalue) select) && typeset -p my_array
  -ksh: syntax error: `select' unexpected

Analysis: The problem is in the assign() function in parse.c. From
the second value element on, reserved words/keywords are wrongly
recognised when assign() is called recursively to parse
multidimensional array assignments, because the lexer flag
'noreserv' is reset to zero in the course of the assign() call.

src/cmd/ksh93/sh/parse.c: assign():
- After recursively calling assign() to deal with nested
  parentheses, set noreserv to back to 1 to re-disable the
  recognition of reserved words by the lexer.

Thanks to @TristanJamesBall for the report.
Resolves: #790
  • Loading branch information
McDutchie committed Oct 23, 2024
1 parent b6f44cf commit 7da8ce1
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 2 deletions.
8 changes: 8 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@ This documents significant changes in the dev branch of ksh 93u+m.
For full details, see the git log at: https://github.com/ksh93/ksh
Uppercase BUG_* IDs are shell bug IDs as used by the Modernish shell library.

2024-10-23:

- Fixed a bug in multidimensional indexed array assignments where unquoted
values that corresponded to reserved words (such as 'if' or 'select')
incorrectly caused a syntax error. For example,
my_array=((somevalue) select) && typeset -p my_array
now works as expected. This bug was introduced in ksh 93r+ 2006-06-30.

2024-08-28:

- Fixed a crash that occurred for an arithmetic 'for' that has two instead of
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/ksh93/include/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

#define SH_RELEASE_FORK "93u+m" /* only change if you develop a new ksh93 fork */
#define SH_RELEASE_SVER "1.1.0-alpha" /* semantic version number: https://semver.org */
#define SH_RELEASE_DATE "2024-08-28" /* must be in this format for $((.sh.version)) */
#define SH_RELEASE_DATE "2024-10-23" /* must be in this format for $((.sh.version)) */
#define SH_RELEASE_CPYR "(c) 2020-2024 Contributors to ksh " SH_RELEASE_FORK

/* Scripts sometimes field-split ${.sh.version}, so don't change amount of whitespace. */
Expand Down
4 changes: 4 additions & 0 deletions src/cmd/ksh93/sh/parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -1053,7 +1053,11 @@ static struct argnod *assign(Lex_t *lexp, struct argnod *ap, int type)
ar = stkfreeze(sh.stk,1);
ar->argnxt.ap = 0;
if(!aq)
{
ar = assign(lexp,ar,0);
/* since noreserv is reset to 0 below, we have set it again after a recursive call */
lexp->noreserv = 1;
}
ar->argflag |= ARG_MESSAGE;
*settail = ar;
settail = &(ar->argnxt.ap);
Expand Down
22 changes: 21 additions & 1 deletion src/cmd/ksh93/tests/arrays2.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# #
# This software is part of the ast package #
# Copyright (c) 1982-2012 AT&T Intellectual Property #
# Copyright (c) 2020-2023 Contributors to ksh 93u+m #
# Copyright (c) 2020-2024 Contributors to ksh 93u+m #
# and is licensed under the #
# Eclipse Public License, Version 2.0 #
# #
Expand Down Expand Up @@ -305,5 +305,25 @@ got=$(typeset -a arr=(a (b d e) c d e); echo ${arr[@]:2:${#arr[@]}-2})
got=$(typeset -A arr=(a (b d e) c d e); echo ${arr[@]:2:${#arr[@]}-2})
[[ $got == "$exp" ]] || err_exit "array slicing test 13 (expected $(printf %q "$exp"), got $(printf %q "$got"))"

# ======
# Reserved words as values
# https://github.com/ksh93/ksh/issues/790
got=$(set +x; eval 'typeset -a a1=((demo) (select) (if) (case) (while))' 2>&1 && typeset -p a1)
exp='typeset -a a1=((demo) (select) (if) (case) (while) )'
[[ $got == "$exp" ]] || err_exit "reserved word assigned as multidimensional array value" \
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
got=$(set +x; eval 'typeset -a a1=((demo) (select) if case while)' 2>&1 && typeset -p a1)
exp='typeset -a a1=((demo) (select) if case while)'
[[ $got == "$exp" ]] || err_exit "reserved word assigned as top-level value in multidimensional array" \
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
got=$(set +x; eval 'a1=((demo) (select) (if) (case) (while))' 2>&1 && typeset -p a1)
exp='typeset -a a1=((demo) (select) (if) (case) (while) )'
[[ $got == "$exp" ]] || err_exit "reserved word assigned as implicit multidimensional array value" \
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
got=$(set +x; eval 'a1=((demo) (select) if case while)' 2>&1 && typeset -p a1)
exp='typeset -a a1=((demo) (select) if case while)'
[[ $got == "$exp" ]] || err_exit "reserved word assigned as top-level value in implicit multidimensional array" \
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"

# ======
exit $((Errors<125?Errors:125))

0 comments on commit 7da8ce1

Please sign in to comment.