7 Bug-Reported-by: Bruce Jerrick
9 Bug-Reference-URL: https://bugzilla.redhat.com/show_bug.cgi?id=2134307
13 This patch fixes several problems with alias expansion inside command
14 substitutions when in POSIX mode.
16 Patch (apply with `patch -p0'):
18 *** /fs1/chet/scratch/bash-5.2.6/parse.y 2022-11-02 10:36:54.000000000 -0400
19 --- parse.y 2022-10-24 10:53:26.000000000 -0400
23 #define P_ARRAYSUB 0x0020 /* parsing a [...] array subscript for assignment */
24 #define P_DOLBRACE 0x0040 /* parsing a ${...} construct */
25 + #define P_ARITH 0x0080 /* parsing a $(( )) arithmetic expansion */
27 /* Lexical state while parsing a grouping construct or $(...). */
31 else if ((flags & (P_ARRAYSUB|P_DOLBRACE)) && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
32 goto parse_dollar_word;
33 + else if ((flags & P_ARITH) && (tflags & LEX_WASDOL) && ch == '(') /*)*/
34 + /* $() inside $(( ))/$[ ] */
35 + goto parse_dollar_word;
36 #if defined (PROCESS_SUBSTITUTION)
37 /* XXX - technically this should only be recognized at the start of
40 nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|P_DOLBRACE|rflags);
41 else if (ch == '[') /* ] */
42 ! nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags);
44 CHECK_NESTRET_ERROR ();
46 nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|P_DOLBRACE|rflags);
47 else if (ch == '[') /* ] */
48 ! nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags|P_ARITH);
50 CHECK_NESTRET_ERROR ();
54 if (peekc == '(') /*)*/
55 ! return (parse_matched_pair (qc, open, close, lenp, 0));
60 if (peekc == '(') /*)*/
61 ! return (parse_matched_pair (qc, open, close, lenp, P_ARITH));
67 exp_lineno = line_number;
68 ! ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
70 if (ttok == &matched_pair_error)
73 exp_lineno = line_number;
74 ! ttok = parse_matched_pair (0, '(', ')', &ttoklen, P_ARITH);
76 if (ttok == &matched_pair_error)
81 ! ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
82 if (ttok == &matched_pair_error)
83 return -1; /* Bail immediately. */
87 ! ttok = parse_matched_pair (cd, '[', ']', &ttoklen, P_ARITH);
88 if (ttok == &matched_pair_error)
89 return -1; /* Bail immediately. */
90 *** ../bash-5.2.6/y.tab.c 2022-11-02 10:36:54.000000000 -0400
91 --- y.tab.c 2022-11-02 10:55:58.000000000 -0400
95 #define P_ARRAYSUB 0x0020 /* parsing a [...] array subscript for assignment */
96 #define P_DOLBRACE 0x0040 /* parsing a ${...} construct */
97 + #define P_ARITH 0x0080 /* parsing a $(( )) arithmetic expansion */
99 /* Lexical state while parsing a grouping construct or $(...). */
103 else if ((flags & (P_ARRAYSUB|P_DOLBRACE)) && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
104 goto parse_dollar_word;
105 + else if ((flags & P_ARITH) && (tflags & LEX_WASDOL) && ch == '(') /*)*/
106 + /* $() inside $(( ))/$[ ] */
107 + goto parse_dollar_word;
108 #if defined (PROCESS_SUBSTITUTION)
109 /* XXX - technically this should only be recognized at the start of
112 nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|P_DOLBRACE|rflags);
113 else if (ch == '[') /* ] */
114 ! nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags);
116 CHECK_NESTRET_ERROR ();
118 nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|P_DOLBRACE|rflags);
119 else if (ch == '[') /* ] */
120 ! nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags|P_ARITH);
122 CHECK_NESTRET_ERROR ();
125 shell_ungetc (peekc);
126 if (peekc == '(') /*)*/
127 ! return (parse_matched_pair (qc, open, close, lenp, 0));
131 shell_ungetc (peekc);
132 if (peekc == '(') /*)*/
133 ! return (parse_matched_pair (qc, open, close, lenp, P_ARITH));
139 exp_lineno = line_number;
140 ! ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
142 if (ttok == &matched_pair_error)
145 exp_lineno = line_number;
146 ! ttok = parse_matched_pair (0, '(', ')', &ttoklen, P_ARITH);
148 if (ttok == &matched_pair_error)
153 ! ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
154 if (ttok == &matched_pair_error)
155 return -1; /* Bail immediately. */
159 ! ttok = parse_matched_pair (cd, '[', ']', &ttoklen, P_ARITH);
160 if (ttok == &matched_pair_error)
161 return -1; /* Bail immediately. */
162 *** /fs1/chet/scratch/bash-5.2.6/builtins/evalstring.c 2022-07-18 14:46:56.000000000 -0400
163 --- builtins/evalstring.c 2022-10-18 10:57:51.000000000 -0400
167 if (parse_command () == 0)
169 + int local_expalias, local_alflag;
171 if ((flags & SEVAL_PARSEONLY) || (interactive_shell == 0 && read_but_dont_execute))
178 + /* We play tricks in the parser and command_substitute() turning
179 + expand_aliases on and off depending on which parsing pass and
180 + whether or not we're in posix mode. This only matters for
181 + parsing, and we let the higher layers deal with that. We just
182 + want to ensure that expand_aliases is set to the appropriate
183 + global value when we go to execute this command, so we save
184 + and restore it around the execution (we don't restore it if
185 + the global value of the flag (expaliases_flag) changes). */
186 + local_expalias = expand_aliases;
187 + local_alflag = expaliases_flag;
188 + if (subshell_environment & SUBSHELL_COMSUB)
189 + expand_aliases = expaliases_flag;
191 /* See if this is a candidate for $( <file ). */
192 if (startup_state == 2 &&
196 discard_unwind_frame ("pe_dispose");
198 + /* If the global value didn't change, we restore what we had. */
199 + if ((subshell_environment & SUBSHELL_COMSUB) && local_alflag == expaliases_flag)
200 + expand_aliases = local_expalias;
202 if (flags & SEVAL_ONECMD)
204 *** /fs1/chet/scratch/bash-5.2.6/command.h 2021-04-30 15:43:15.000000000 -0400
205 --- command.h 2022-10-18 11:44:31.000000000 -0400
209 #define PF_EXPANDRHS 0x20 /* same as W_EXPANDRHS */
210 #define PF_ALLINDS 0x40 /* array, act as if [@] was supplied */
211 + #define PF_BACKQUOTE 0x80 /* differentiate `` from $() for command_substitute */
213 /* Possible values for subshell_environment */
214 *** /fs1/chet/scratch/bash-5.2.6/subst.c 2022-11-02 10:28:10.000000000 -0400
215 --- subst.c 2022-10-20 12:41:07.000000000 -0400
219 /* We want to expand aliases on this pass if we are not in posix mode
220 ! for backwards compatibility. */
221 ! if (expand_aliases)
222 expand_aliases = posixly_correct == 0;
226 /* We want to expand aliases on this pass if we are not in posix mode
227 ! for backwards compatibility. parse_and_execute() takes care of
228 ! setting expand_aliases back to the global value when executing the
229 ! parsed string. We only do this for $(...) command substitution,
230 ! since that is what parse_comsub handles; `` comsubs are processed
231 ! using parse.y:parse_matched_pair(). */
232 ! if (expand_aliases && (flags & PF_BACKQUOTE) == 0)
233 expand_aliases = posixly_correct == 0;
239 ! tword = command_substitute (temp, quoted, 0);
240 temp1 = tword ? tword->word : (char *)NULL;
245 ! tword = command_substitute (temp, quoted, PF_BACKQUOTE);
246 temp1 = tword ? tword->word : (char *)NULL;
248 *** ../bash-5.2/patchlevel.h 2020-06-22 14:51:03.000000000 -0400
249 --- patchlevel.h 2020-10-01 11:01:28.000000000 -0400
252 looks for to find the patch level (for the sccs version string). */
254 ! #define PATCHLEVEL 6
256 #endif /* _PATCHLEVEL_H_ */
258 looks for to find the patch level (for the sccs version string). */
260 ! #define PATCHLEVEL 7
262 #endif /* _PATCHLEVEL_H_ */