From b7b9d7c306b2881560c4f94b7e7c7175f851c891 Mon Sep 17 00:00:00 2001 From: Chet Ramey Date: Thu, 1 Sep 2022 10:25:58 -0400 Subject: [PATCH] fix for problem with command substitutions inside aliases --- CWRU/CWRU.chlog | 18 ++++++++++++++++++ MANIFEST | 1 + parse.y | 20 +++++++++++++++----- subst.c | 2 +- tests/RUN-ONE-TEST | 2 +- tests/comsub.right | 11 +++++++++++ tests/comsub.tests | 1 + tests/comsub6.sub | 40 ++++++++++++++++++++++++++++++++++++++++ tests/new-exp.right | 1 + tests/new-exp10.sub | 3 +++ tests/new-exp14.sub | 2 +- 11 files changed, 93 insertions(+), 8 deletions(-) create mode 100644 tests/comsub6.sub diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 317a9460..456ac024 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -3914,3 +3914,21 @@ parse.y issue reported by Kerin Millar - cond_term: restore extended_glob to a local copy; safer than using global_extglob, which we will reserve for error recovery + + 8/30 + ---- +parse.y + - parse_comsub: don't clear the pushed string list; we might need it to + consume additional input to satisfy this command substitution. When + we restore the parser state, don't restore the pushed string list in + case we used it. From + https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1018727 + - parse_comsub: don't modify extended_glob if parser_state includes + PST_EXTPAT, in which case we've already set extended_glob and + global_extglob appropriately. Only matters in compatibility mode. + + 8/31 + ---- +subst.c + - parameter_brace_transform: make sure we return an error if *xform + is '\0'. Report from Ivan Kapranov diff --git a/MANIFEST b/MANIFEST index 4bd7f0fb..90d94686 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1002,6 +1002,7 @@ tests/comsub2.sub f tests/comsub3.sub f tests/comsub4.sub f tests/comsub5.sub f +tests/comsub6.sub f tests/comsub-eof.tests f tests/comsub-eof0.sub f tests/comsub-eof1.sub f diff --git a/parse.y b/parse.y index 4922d129..d887eecb 100644 --- a/parse.y +++ b/parse.y @@ -4063,10 +4063,11 @@ parse_comsub (qc, open, close, lenp, flags) int *lenp, flags; { int peekc, r; - int start_lineno, local_extglob; + int start_lineno, local_extglob, was_extpat; char *ret, *tcmd; int retlen; sh_parser_state_t ps; + STRING_SAVER *saved_strings; COMMAND *saved_global, *parsed_command; /* Posix interp 217 says arithmetic expressions have precedence, so @@ -4086,7 +4087,7 @@ parse_comsub (qc, open, close, lenp, flags) save_parser_state (&ps); - pushed_string_list = (STRING_SAVER *)NULL; + was_extpat = (parser_state & PST_EXTPAT); /* State flags we don't want to persist into command substitutions. */ parser_state &= ~(PST_REGEXP|PST_EXTPAT|PST_CONDCMD|PST_CONDEXPR|PST_COMPASSIGN); @@ -4098,6 +4099,8 @@ parse_comsub (qc, open, close, lenp, flags) /* State flags we want to set for this run through the parser. */ parser_state |= PST_CMDSUBST|PST_EOFTOKEN|PST_NOEXPAND; + /* leave pushed_string_list alone, since we might need to consume characters + from it to satisfy this command substitution (in some perverse case). */ shell_eof_token = close; saved_global = global_command; /* might not be necessary */ @@ -4114,7 +4117,9 @@ parse_comsub (qc, open, close, lenp, flags) if (expand_aliases) expand_aliases = posixly_correct != 0; #if defined (EXTENDED_GLOB) - if (shell_compatibility_level <= 51) + /* If (parser_state & PST_EXTPAT), we're parsing an extended pattern for a + conditional command and have already set global_extglob appropriately. */ + if (shell_compatibility_level <= 51 && was_extpat == 0) { local_extglob = global_extglob = extended_glob; extended_glob = 1; @@ -4133,7 +4138,7 @@ parse_comsub (qc, open, close, lenp, flags) } #if defined (EXTENDED_GLOB) - if (shell_compatibility_level <= 51) + if (shell_compatibility_level <= 51 && was_extpat == 0) extended_glob = local_extglob; #endif @@ -4161,7 +4166,7 @@ parse_comsub (qc, open, close, lenp, flags) shell_eof_token = ps.eof_token; expand_aliases = ps.expand_aliases; - jump_to_top_level (DISCARD); + jump_to_top_level (DISCARD); /* XXX - return (&matched_pair_error)? */ } } @@ -4180,7 +4185,12 @@ INTERNAL_DEBUG(("current_token (%d) != shell_eof_token (%c)", current_token, she return (&matched_pair_error); } + /* We don't want to restore the old pushed string list, since we might have + used it to consume additional input from an alias while parsing this + command substitution. */ + saved_strings = pushed_string_list; restore_parser_state (&ps); + pushed_string_list = saved_strings; tcmd = print_comsub (parsed_command); /* returns static memory */ retlen = strlen (tcmd); diff --git a/subst.c b/subst.c index f2987a51..d9feabca 100644 --- a/subst.c +++ b/subst.c @@ -8660,7 +8660,7 @@ parameter_brace_transform (varname, value, estatep, xform, rtype, quoted, pflags return ((char *)NULL); } - if (valid_parameter_transform (xform) == 0) + if (xform[0] == 0 || valid_parameter_transform (xform) == 0) { this_command_name = oname; if (vtype == VT_VARIABLE) diff --git a/tests/RUN-ONE-TEST b/tests/RUN-ONE-TEST index 0b063810..c8bef8dd 100755 --- a/tests/RUN-ONE-TEST +++ b/tests/RUN-ONE-TEST @@ -1,4 +1,4 @@ -BUILD_DIR=/usr/local/build/chet/bash/bash-current +BUILD_DIR=/usr/local/build/bash/bash-current THIS_SH=$BUILD_DIR/bash PATH=$PATH:$BUILD_DIR diff --git a/tests/comsub.right b/tests/comsub.right index 3d478713..eae8c3b2 100644 --- a/tests/comsub.right +++ b/tests/comsub.right @@ -66,3 +66,14 @@ ok 7 ok 9 ok 8 ok 8 +Mon Aug 29 20:03:02 EDT 2022 +post foo +Mon Aug 29 20:03:02 EDT 2022 +post foo1 +Mon Aug 29 20:03:02 EDT 2022 +Mon Aug 29 20:03:02 EDT 2022 after +7 +Mon Aug 29 20:03:02 EDT 2022 +hey after x +./comsub6.sub: line 40: syntax error near unexpected token `)' +./comsub6.sub: line 40: `math1)' diff --git a/tests/comsub.tests b/tests/comsub.tests index 2c2107f9..698ce30b 100644 --- a/tests/comsub.tests +++ b/tests/comsub.tests @@ -81,3 +81,4 @@ ${THIS_SH} ./comsub2.sub ${THIS_SH} ./comsub3.sub ${THIS_SH} ./comsub4.sub ${THIS_SH} ./comsub5.sub +${THIS_SH} ./comsub6.sub diff --git a/tests/comsub6.sub b/tests/comsub6.sub new file mode 100644 index 00000000..d2b02bf4 --- /dev/null +++ b/tests/comsub6.sub @@ -0,0 +1,40 @@ +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +DATE='Mon Aug 29 20:03:02 EDT 2022' +shopt -s expand_aliases + +alias foo='echo $(echo $DATE)' +alias foo1='echo $(echo $DATE) ' + +foo +echo post foo + +foo1 +echo post foo1 + +alias comsub0='echo $(echo $DATE' +comsub0) +comsub0 ) after + +alias math0='echo $(( 4+3 )' +math0) + +alias x='VAR=$(echo hey)' +x +foo + +echo $VAR after x + +alias math1='echo $( date )' +math1) diff --git a/tests/new-exp.right b/tests/new-exp.right index 2d4d9b82..e3dc40e1 100644 --- a/tests/new-exp.right +++ b/tests/new-exp.right @@ -648,6 +648,7 @@ i declare -i foo A declare -A foo +./new-exp10.sub: line 118: ${V@}: bad substitution abcxxxdef abcÃ¥def ḅć diff --git a/tests/new-exp10.sub b/tests/new-exp10.sub index 8c1f364e..5b199d4f 100644 --- a/tests/new-exp10.sub +++ b/tests/new-exp10.sub @@ -113,3 +113,6 @@ declare -A foo echo ${foo@a} declare -p foo + +V=42 +echo ${V@} # error diff --git a/tests/new-exp14.sub b/tests/new-exp14.sub index ce963763..92f51ea1 100644 --- a/tests/new-exp14.sub +++ b/tests/new-exp14.sub @@ -12,7 +12,7 @@ # along with this program. If not, see . # -# test the other uses of the 'K' tranform operator and its sibling 'k' +# test the other uses of the 'K' transform operator and its sibling 'k' # the associative array tests are performed separately, since that was the # original motivation for this feature foo=string