Bash-5.2 patch 7: fixes for alias expansion inside command substitution in POSIX mode

This commit is contained in:
Chet Ramey
2022-11-07 11:42:44 -05:00
parent 8c9524f9c4
commit 6ddc9cf242
6 changed files with 44 additions and 12 deletions
+19
View File
@@ -431,6 +431,8 @@ parse_and_execute (string, from_file, flags)
if (parse_command () == 0)
{
int local_expalias, local_alflag;
if ((flags & SEVAL_PARSEONLY) || (interactive_shell == 0 && read_but_dont_execute))
{
last_result = EXECUTION_SUCCESS;
@@ -507,6 +509,19 @@ parse_and_execute (string, from_file, flags)
}
#endif /* ONESHOT */
/* We play tricks in the parser and command_substitute() turning
expand_aliases on and off depending on which parsing pass and
whether or not we're in posix mode. This only matters for
parsing, and we let the higher layers deal with that. We just
want to ensure that expand_aliases is set to the appropriate
global value when we go to execute this command, so we save
and restore it around the execution (we don't restore it if
the global value of the flag (expaliases_flag) changes). */
local_expalias = expand_aliases;
local_alflag = expaliases_flag;
if (subshell_environment & SUBSHELL_COMSUB)
expand_aliases = expaliases_flag;
/* See if this is a candidate for $( <file ). */
if (startup_state == 2 &&
(subshell_environment & SUBSHELL_COMSUB) &&
@@ -524,6 +539,10 @@ parse_and_execute (string, from_file, flags)
dispose_fd_bitmap (bitmap);
discard_unwind_frame ("pe_dispose");
/* If the global value didn't change, we restore what we had. */
if ((subshell_environment & SUBSHELL_COMSUB) && local_alflag == expaliases_flag)
expand_aliases = local_expalias;
if (flags & SEVAL_ONECMD)
{
reset_parser ();
+1
View File
@@ -114,6 +114,7 @@ enum command_type { cm_for, cm_case, cm_while, cm_if, cm_simple, cm_select,
#define PF_COMPLETE 0x10 /* same as W_COMPLETE, sets SX_COMPLETE */
#define PF_EXPANDRHS 0x20 /* same as W_EXPANDRHS */
#define PF_ALLINDS 0x40 /* array, act as if [@] was supplied */
#define PF_BACKQUOTE 0x80 /* differentiate `` from $() for command_substitute */
/* Possible values for subshell_environment */
#define SUBSHELL_ASYNC 0x01 /* subshell caused by `command &' */
+8 -4
View File
@@ -3612,6 +3612,7 @@ tokword:
#define P_BACKQUOTE 0x0010 /* parsing a backquoted command substitution */
#define P_ARRAYSUB 0x0020 /* parsing a [...] array subscript for assignment */
#define P_DOLBRACE 0x0040 /* parsing a ${...} construct */
#define P_ARITH 0x0080 /* parsing a $(( )) arithmetic expansion */
/* Lexical state while parsing a grouping construct or $(...). */
#define LEX_WASDOL 0x0001
@@ -3910,6 +3911,9 @@ parse_matched_pair (qc, open, close, lenp, flags)
}
else if ((flags & (P_ARRAYSUB|P_DOLBRACE)) && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
goto parse_dollar_word;
else if ((flags & P_ARITH) && (tflags & LEX_WASDOL) && ch == '(') /*)*/
/* $() inside $(( ))/$[ ] */
goto parse_dollar_word;
#if defined (PROCESS_SUBSTITUTION)
/* XXX - technically this should only be recognized at the start of
a word */
@@ -3940,7 +3944,7 @@ parse_dollar_word:
else if (ch == '{') /* } */
nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|P_DOLBRACE|rflags);
else if (ch == '[') /* ] */
nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags);
nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags|P_ARITH);
CHECK_NESTRET_ERROR ();
APPEND_NESTRET ();
@@ -4079,7 +4083,7 @@ parse_comsub (qc, open, close, lenp, flags)
peekc = shell_getc (1);
shell_ungetc (peekc);
if (peekc == '(') /*)*/
return (parse_matched_pair (qc, open, close, lenp, 0));
return (parse_matched_pair (qc, open, close, lenp, P_ARITH));
}
/*itrace("parse_comsub: qc = `%c' open = %c close = %c", qc, open, close);*/
@@ -4500,7 +4504,7 @@ parse_arith_cmd (ep, adddq)
int ttoklen;
exp_lineno = line_number;
ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
ttok = parse_matched_pair (0, '(', ')', &ttoklen, P_ARITH);
rval = 1;
if (ttok == &matched_pair_error)
return -1;
@@ -5015,7 +5019,7 @@ read_token_word (character)
pop_delimiter (dstack);
}
else
ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
ttok = parse_matched_pair (cd, '[', ']', &ttoklen, P_ARITH);
if (ttok == &matched_pair_error)
return -1; /* Bail immediately. */
RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 3,
+1 -1
View File
@@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
#define PATCHLEVEL 6
#define PATCHLEVEL 7
#endif /* _PATCHLEVEL_H_ */
+7 -3
View File
@@ -7123,8 +7123,12 @@ command_substitute (string, quoted, flags)
remove_quoted_escapes (string);
/* We want to expand aliases on this pass if we are not in posix mode
for backwards compatibility. */
if (expand_aliases)
for backwards compatibility. parse_and_execute() takes care of
setting expand_aliases back to the global value when executing the
parsed string. We only do this for $(...) command substitution,
since that is what parse_comsub handles; `` comsubs are processed
using parse.y:parse_matched_pair(). */
if (expand_aliases && (flags & PF_BACKQUOTE) == 0)
expand_aliases = posixly_correct == 0;
startup_state = 2; /* see if we can avoid a fork */
@@ -11292,7 +11296,7 @@ add_string:
else
{
de_backslash (temp);
tword = command_substitute (temp, quoted, 0);
tword = command_substitute (temp, quoted, PF_BACKQUOTE);
temp1 = tword ? tword->word : (char *)NULL;
if (tword)
dispose_word_desc (tword);
+8 -4
View File
@@ -5923,6 +5923,7 @@ tokword:
#define P_BACKQUOTE 0x0010 /* parsing a backquoted command substitution */
#define P_ARRAYSUB 0x0020 /* parsing a [...] array subscript for assignment */
#define P_DOLBRACE 0x0040 /* parsing a ${...} construct */
#define P_ARITH 0x0080 /* parsing a $(( )) arithmetic expansion */
/* Lexical state while parsing a grouping construct or $(...). */
#define LEX_WASDOL 0x0001
@@ -6221,6 +6222,9 @@ parse_matched_pair (qc, open, close, lenp, flags)
}
else if ((flags & (P_ARRAYSUB|P_DOLBRACE)) && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
goto parse_dollar_word;
else if ((flags & P_ARITH) && (tflags & LEX_WASDOL) && ch == '(') /*)*/
/* $() inside $(( ))/$[ ] */
goto parse_dollar_word;
#if defined (PROCESS_SUBSTITUTION)
/* XXX - technically this should only be recognized at the start of
a word */
@@ -6251,7 +6255,7 @@ parse_dollar_word:
else if (ch == '{') /* } */
nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|P_DOLBRACE|rflags);
else if (ch == '[') /* ] */
nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags);
nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags|P_ARITH);
CHECK_NESTRET_ERROR ();
APPEND_NESTRET ();
@@ -6390,7 +6394,7 @@ parse_comsub (qc, open, close, lenp, flags)
peekc = shell_getc (1);
shell_ungetc (peekc);
if (peekc == '(') /*)*/
return (parse_matched_pair (qc, open, close, lenp, 0));
return (parse_matched_pair (qc, open, close, lenp, P_ARITH));
}
/*itrace("parse_comsub: qc = `%c' open = %c close = %c", qc, open, close);*/
@@ -6811,7 +6815,7 @@ parse_arith_cmd (ep, adddq)
int ttoklen;
exp_lineno = line_number;
ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
ttok = parse_matched_pair (0, '(', ')', &ttoklen, P_ARITH);
rval = 1;
if (ttok == &matched_pair_error)
return -1;
@@ -7326,7 +7330,7 @@ read_token_word (character)
pop_delimiter (dstack);
}
else
ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
ttok = parse_matched_pair (cd, '[', ']', &ttoklen, P_ARITH);
if (ttok == &matched_pair_error)
return -1; /* Bail immediately. */
RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 3,