7 Bug-Reported-by: Mike Frysinger <vapier@gentoo.org>
8 Bug-Reference-ID: <200902211821.42188.vapier@gentoo.org>
9 Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2009-02/msg00147.html
13 Bash has problems parsing certain constructs inside Posix-style $(...)
14 command substitutions, mostly with backslash-quoting and reserved word
15 recognition. This is an issue because the contents are parsed at the
16 time the word containing the command substitution is read.
20 *** ../bash-4.0/parse.y 2009-01-08 08:29:12.000000000 -0500
21 --- parse.y 2009-03-06 20:32:35.000000000 -0500
25 #define LEX_HEREDELIM 0x100 /* reading here-doc delimiter */
26 #define LEX_STRIPDOC 0x200 /* <<- strip tabs from here doc delim */
27 + #define LEX_INWORD 0x400
29 #define COMSUB_META(ch) ((ch) == ';' || (ch) == '&' || (ch) == '|')
34 ! int count, ch, peekc, tflags, lex_rwlen, lex_firstind;
35 int nestlen, ttranslen, start_lineno;
36 char *ret, *nestret, *ttrans, *heredelim;
40 ! int count, ch, peekc, tflags, lex_rwlen, lex_wlen, lex_firstind;
41 int nestlen, ttranslen, start_lineno;
42 char *ret, *nestret, *ttrans, *heredelim;
46 start_lineno = line_number;
52 start_lineno = line_number;
53 ! lex_rwlen = lex_wlen = 0;
61 + if (tflags & LEX_PASSNEXT) /* last char was backslash */
63 + /*itrace("parse_comsub:%d: lex_passnext -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/
64 + tflags &= ~LEX_PASSNEXT;
65 + if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
68 + retind--; /* swallow previously-added backslash */
72 + RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
73 + if MBTEST(ch == CTLESC || ch == CTLNUL)
74 + ret[retind++] = CTLESC;
79 + /* If this is a shell break character, we are not in a word. If not,
80 + we either start or continue a word. */
81 + if MBTEST(shellbreak (ch))
83 + tflags &= ~LEX_INWORD;
84 + /*itrace("parse_comsub:%d: lex_inword -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/
88 + if (tflags & LEX_INWORD)
91 + /*itrace("parse_comsub:%d: lex_inword == 1 ch = `%c' lex_wlen = %d (%d)", line_number, ch, lex_wlen, __LINE__);*/
95 + /*itrace("parse_comsub:%d: lex_inword -> 1 ch = `%c' (%d)", line_number, ch, __LINE__);*/
96 + tflags |= LEX_INWORD;
101 /* Skip whitespace */
102 if MBTEST(shellblank (ch) && lex_rwlen == 0)
107 ! ch = peekc; /* fall through and continue XXX - this skips comments if peekc == '#' */
109 ! /* Not exactly right yet, should handle shell metacharacters, too. If
110 ! any changes are made to this test, make analogous changes to subst.c:
111 ! extract_delimited_string(). */
112 ! else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (retind == 0 || ret[retind-1] == '\n' || shellblank (ret[retind - 1])))
113 tflags |= LEX_INCOMMENT;
115 ! if (tflags & LEX_PASSNEXT) /* last char was backslash */
117 ! tflags &= ~LEX_PASSNEXT;
118 ! if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
121 ! retind--; /* swallow previously-added backslash */
125 ! RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
126 ! if MBTEST(ch == CTLESC || ch == CTLNUL)
127 ! ret[retind++] = CTLESC;
128 ! ret[retind++] = ch;
131 ! else if MBTEST(ch == CTLESC || ch == CTLNUL) /* special shell escapes */
133 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
137 ! ch = peekc; /* fall through and continue XXX */
139 ! else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (((tflags & LEX_RESWDOK) && lex_rwlen == 0) || ((tflags & LEX_INWORD) && lex_wlen == 0)))
141 ! /*itrace("parse_comsub:%d: lex_incomment -> 1 (%d)", line_number, __LINE__);*/
142 tflags |= LEX_INCOMMENT;
145 ! if MBTEST(ch == CTLESC || ch == CTLNUL) /* special shell escapes */
147 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
148 *** ../bash-4.0/patchlevel.h 2009-01-04 14:32:40.000000000 -0500
149 --- patchlevel.h 2009-02-22 16:11:31.000000000 -0500
152 looks for to find the patch level (for the sccs version string). */
154 ! #define PATCHLEVEL 0
156 #endif /* _PATCHLEVEL_H_ */
158 looks for to find the patch level (for the sccs version string). */
160 ! #define PATCHLEVEL 1
162 #endif /* _PATCHLEVEL_H_ */