]>
Commit | Line | Data |
---|---|---|
39cb2ba7 AM |
1 | BASH PATCH REPORT |
2 | ================= | |
3 | ||
4 | Bash-Release: 4.0 | |
5 | Patch-ID: bash40-001 | |
6 | ||
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 | |
10 | ||
11 | Bug-Description: | |
12 | ||
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. | |
17 | ||
18 | Patch: | |
19 | ||
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 | |
22 | *************** | |
23 | *** 2928,2931 **** | |
24 | --- 2932,2936 ---- | |
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 | |
28 | ||
29 | #define COMSUB_META(ch) ((ch) == ';' || (ch) == '&' || (ch) == '|') | |
30 | *************** | |
31 | *** 3180,3184 **** | |
32 | int *lenp, flags; | |
33 | { | |
34 | ! int count, ch, peekc, tflags, lex_rwlen, lex_firstind; | |
35 | int nestlen, ttranslen, start_lineno; | |
36 | char *ret, *nestret, *ttrans, *heredelim; | |
37 | --- 3188,3192 ---- | |
38 | int *lenp, flags; | |
39 | { | |
40 | ! int count, ch, peekc, tflags, lex_rwlen, lex_wlen, lex_firstind; | |
41 | int nestlen, ttranslen, start_lineno; | |
42 | char *ret, *nestret, *ttrans, *heredelim; | |
43 | *************** | |
44 | *** 3201,3205 **** | |
45 | ||
46 | start_lineno = line_number; | |
47 | ! lex_rwlen = 0; | |
48 | ||
49 | heredelim = 0; | |
50 | --- 3209,3213 ---- | |
51 | ||
52 | start_lineno = line_number; | |
53 | ! lex_rwlen = lex_wlen = 0; | |
54 | ||
55 | heredelim = 0; | |
56 | *************** | |
57 | *** 3268,3271 **** | |
58 | --- 3276,3319 ---- | |
59 | } | |
60 | ||
61 | + if (tflags & LEX_PASSNEXT) /* last char was backslash */ | |
62 | + { | |
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. */ | |
66 | + { | |
67 | + if (retind > 0) | |
68 | + retind--; /* swallow previously-added backslash */ | |
69 | + continue; | |
70 | + } | |
71 | + | |
72 | + RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64); | |
73 | + if MBTEST(ch == CTLESC || ch == CTLNUL) | |
74 | + ret[retind++] = CTLESC; | |
75 | + ret[retind++] = ch; | |
76 | + continue; | |
77 | + } | |
78 | + | |
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)) | |
82 | + { | |
83 | + tflags &= ~LEX_INWORD; | |
84 | + /*itrace("parse_comsub:%d: lex_inword -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/ | |
85 | + } | |
86 | + else | |
87 | + { | |
88 | + if (tflags & LEX_INWORD) | |
89 | + { | |
90 | + lex_wlen++; | |
91 | + /*itrace("parse_comsub:%d: lex_inword == 1 ch = `%c' lex_wlen = %d (%d)", line_number, ch, lex_wlen, __LINE__);*/ | |
92 | + } | |
93 | + else | |
94 | + { | |
95 | + /*itrace("parse_comsub:%d: lex_inword -> 1 ch = `%c' (%d)", line_number, ch, __LINE__);*/ | |
96 | + tflags |= LEX_INWORD; | |
97 | + lex_wlen = 0; | |
98 | + } | |
99 | + } | |
100 | + | |
101 | /* Skip whitespace */ | |
102 | if MBTEST(shellblank (ch) && lex_rwlen == 0) | |
103 | *************** | |
104 | *** 3400,3428 **** | |
105 | } | |
106 | else | |
107 | ! ch = peekc; /* fall through and continue XXX - this skips comments if peekc == '#' */ | |
108 | } | |
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; | |
114 | ||
115 | ! if (tflags & LEX_PASSNEXT) /* last char was backslash */ | |
116 | ! { | |
117 | ! tflags &= ~LEX_PASSNEXT; | |
118 | ! if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */ | |
119 | ! { | |
120 | ! if (retind > 0) | |
121 | ! retind--; /* swallow previously-added backslash */ | |
122 | ! continue; | |
123 | ! } | |
124 | ! | |
125 | ! RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64); | |
126 | ! if MBTEST(ch == CTLESC || ch == CTLNUL) | |
127 | ! ret[retind++] = CTLESC; | |
128 | ! ret[retind++] = ch; | |
129 | ! continue; | |
130 | ! } | |
131 | ! else if MBTEST(ch == CTLESC || ch == CTLNUL) /* special shell escapes */ | |
132 | { | |
133 | RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64); | |
134 | --- 3442,3454 ---- | |
135 | } | |
136 | else | |
137 | ! ch = peekc; /* fall through and continue XXX */ | |
138 | } | |
139 | ! else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (((tflags & LEX_RESWDOK) && lex_rwlen == 0) || ((tflags & LEX_INWORD) && lex_wlen == 0))) | |
140 | ! { | |
141 | ! /*itrace("parse_comsub:%d: lex_incomment -> 1 (%d)", line_number, __LINE__);*/ | |
142 | tflags |= LEX_INCOMMENT; | |
143 | + } | |
144 | ||
145 | ! if MBTEST(ch == CTLESC || ch == CTLNUL) /* special shell escapes */ | |
146 | { | |
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 | |
150 | *************** | |
151 | *** 26,30 **** | |
152 | looks for to find the patch level (for the sccs version string). */ | |
153 | ||
154 | ! #define PATCHLEVEL 0 | |
155 | ||
156 | #endif /* _PATCHLEVEL_H_ */ | |
157 | --- 26,30 ---- | |
158 | looks for to find the patch level (for the sccs version string). */ | |
159 | ||
160 | ! #define PATCHLEVEL 1 | |
161 | ||
162 | #endif /* _PATCHLEVEL_H_ */ |