|
1 BASH PATCH REPORT |
|
2 ================= |
|
3 |
|
4 Bash-Release: 4.2 |
|
5 Patch-ID: bash42-003 |
|
6 |
|
7 Bug-Reported-by: Clark J. Wang <[email protected]> |
|
8 Bug-Reference-ID: <[email protected]> |
|
9 Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2011-02/msg00136.html |
|
10 |
|
11 Bug-Description: |
|
12 |
|
13 When using the pattern replacement and pattern removal word expansions, bash |
|
14 miscalculates the possible match length in the presence of an unescaped left |
|
15 bracket without a closing right bracket, resulting in a failure to match |
|
16 the pattern. |
|
17 |
|
18 Patch (apply with `patch -p0'): |
|
19 |
|
20 *** ../bash-4.2-patched/lib/glob/gmisc.c 2011-02-05 16:11:17.000000000 -0500 |
|
21 --- lib/glob/gmisc.c 2011-02-18 23:53:42.000000000 -0500 |
|
22 *************** |
|
23 *** 78,83 **** |
|
24 size_t wmax; |
|
25 { |
|
26 ! wchar_t wc, *wbrack; |
|
27 ! int matlen, t, in_cclass, in_collsym, in_equiv; |
|
28 |
|
29 if (*wpat == 0) |
|
30 --- 78,83 ---- |
|
31 size_t wmax; |
|
32 { |
|
33 ! wchar_t wc; |
|
34 ! int matlen, bracklen, t, in_cclass, in_collsym, in_equiv; |
|
35 |
|
36 if (*wpat == 0) |
|
37 *************** |
|
38 *** 119,123 **** |
|
39 case L'[': |
|
40 /* scan for ending `]', skipping over embedded [:...:] */ |
|
41 ! wbrack = wpat; |
|
42 wc = *wpat++; |
|
43 do |
|
44 --- 119,123 ---- |
|
45 case L'[': |
|
46 /* scan for ending `]', skipping over embedded [:...:] */ |
|
47 ! bracklen = 1; |
|
48 wc = *wpat++; |
|
49 do |
|
50 *************** |
|
51 *** 125,140 **** |
|
52 if (wc == 0) |
|
53 { |
|
54 ! matlen += wpat - wbrack - 1; /* incremented below */ |
|
55 ! break; |
|
56 } |
|
57 else if (wc == L'\\') |
|
58 { |
|
59 ! wc = *wpat++; |
|
60 ! if (*wpat == 0) |
|
61 ! break; |
|
62 } |
|
63 else if (wc == L'[' && *wpat == L':') /* character class */ |
|
64 { |
|
65 wpat++; |
|
66 in_cclass = 1; |
|
67 } |
|
68 --- 125,148 ---- |
|
69 if (wc == 0) |
|
70 { |
|
71 ! wpat--; /* back up to NUL */ |
|
72 ! matlen += bracklen; |
|
73 ! goto bad_bracket; |
|
74 } |
|
75 else if (wc == L'\\') |
|
76 { |
|
77 ! /* *wpat == backslash-escaped character */ |
|
78 ! bracklen++; |
|
79 ! /* If the backslash or backslash-escape ends the string, |
|
80 ! bail. The ++wpat skips over the backslash escape */ |
|
81 ! if (*wpat == 0 || *++wpat == 0) |
|
82 ! { |
|
83 ! matlen += bracklen; |
|
84 ! goto bad_bracket; |
|
85 ! } |
|
86 } |
|
87 else if (wc == L'[' && *wpat == L':') /* character class */ |
|
88 { |
|
89 wpat++; |
|
90 + bracklen++; |
|
91 in_cclass = 1; |
|
92 } |
|
93 *************** |
|
94 *** 142,145 **** |
|
95 --- 150,154 ---- |
|
96 { |
|
97 wpat++; |
|
98 + bracklen++; |
|
99 in_cclass = 0; |
|
100 } |
|
101 *************** |
|
102 *** 147,152 **** |
|
103 { |
|
104 wpat++; |
|
105 if (*wpat == L']') /* right bracket can appear as collating symbol */ |
|
106 ! wpat++; |
|
107 in_collsym = 1; |
|
108 } |
|
109 --- 156,165 ---- |
|
110 { |
|
111 wpat++; |
|
112 + bracklen++; |
|
113 if (*wpat == L']') /* right bracket can appear as collating symbol */ |
|
114 ! { |
|
115 ! wpat++; |
|
116 ! bracklen++; |
|
117 ! } |
|
118 in_collsym = 1; |
|
119 } |
|
120 *************** |
|
121 *** 154,157 **** |
|
122 --- 167,171 ---- |
|
123 { |
|
124 wpat++; |
|
125 + bracklen++; |
|
126 in_collsym = 0; |
|
127 } |
|
128 *************** |
|
129 *** 159,164 **** |
|
130 { |
|
131 wpat++; |
|
132 if (*wpat == L']') /* right bracket can appear as equivalence class */ |
|
133 ! wpat++; |
|
134 in_equiv = 1; |
|
135 } |
|
136 --- 173,182 ---- |
|
137 { |
|
138 wpat++; |
|
139 + bracklen++; |
|
140 if (*wpat == L']') /* right bracket can appear as equivalence class */ |
|
141 ! { |
|
142 ! wpat++; |
|
143 ! bracklen++; |
|
144 ! } |
|
145 in_equiv = 1; |
|
146 } |
|
147 *************** |
|
148 *** 166,174 **** |
|
149 --- 184,196 ---- |
|
150 { |
|
151 wpat++; |
|
152 + bracklen++; |
|
153 in_equiv = 0; |
|
154 } |
|
155 + else |
|
156 + bracklen++; |
|
157 } |
|
158 while ((wc = *wpat++) != L']'); |
|
159 matlen++; /* bracket expression can only match one char */ |
|
160 + bad_bracket: |
|
161 break; |
|
162 } |
|
163 *************** |
|
164 *** 214,219 **** |
|
165 size_t max; |
|
166 { |
|
167 ! char c, *brack; |
|
168 ! int matlen, t, in_cclass, in_collsym, in_equiv; |
|
169 |
|
170 if (*pat == 0) |
|
171 --- 236,241 ---- |
|
172 size_t max; |
|
173 { |
|
174 ! char c; |
|
175 ! int matlen, bracklen, t, in_cclass, in_collsym, in_equiv; |
|
176 |
|
177 if (*pat == 0) |
|
178 *************** |
|
179 *** 255,259 **** |
|
180 case '[': |
|
181 /* scan for ending `]', skipping over embedded [:...:] */ |
|
182 ! brack = pat; |
|
183 c = *pat++; |
|
184 do |
|
185 --- 277,281 ---- |
|
186 case '[': |
|
187 /* scan for ending `]', skipping over embedded [:...:] */ |
|
188 ! bracklen = 1; |
|
189 c = *pat++; |
|
190 do |
|
191 *************** |
|
192 *** 261,276 **** |
|
193 if (c == 0) |
|
194 { |
|
195 ! matlen += pat - brack - 1; /* incremented below */ |
|
196 ! break; |
|
197 } |
|
198 else if (c == '\\') |
|
199 { |
|
200 ! c = *pat++; |
|
201 ! if (*pat == 0) |
|
202 ! break; |
|
203 } |
|
204 else if (c == '[' && *pat == ':') /* character class */ |
|
205 { |
|
206 pat++; |
|
207 in_cclass = 1; |
|
208 } |
|
209 --- 283,306 ---- |
|
210 if (c == 0) |
|
211 { |
|
212 ! pat--; /* back up to NUL */ |
|
213 ! matlen += bracklen; |
|
214 ! goto bad_bracket; |
|
215 } |
|
216 else if (c == '\\') |
|
217 { |
|
218 ! /* *pat == backslash-escaped character */ |
|
219 ! bracklen++; |
|
220 ! /* If the backslash or backslash-escape ends the string, |
|
221 ! bail. The ++pat skips over the backslash escape */ |
|
222 ! if (*pat == 0 || *++pat == 0) |
|
223 ! { |
|
224 ! matlen += bracklen; |
|
225 ! goto bad_bracket; |
|
226 ! } |
|
227 } |
|
228 else if (c == '[' && *pat == ':') /* character class */ |
|
229 { |
|
230 pat++; |
|
231 + bracklen++; |
|
232 in_cclass = 1; |
|
233 } |
|
234 *************** |
|
235 *** 278,281 **** |
|
236 --- 308,312 ---- |
|
237 { |
|
238 pat++; |
|
239 + bracklen++; |
|
240 in_cclass = 0; |
|
241 } |
|
242 *************** |
|
243 *** 283,288 **** |
|
244 { |
|
245 pat++; |
|
246 if (*pat == ']') /* right bracket can appear as collating symbol */ |
|
247 ! pat++; |
|
248 in_collsym = 1; |
|
249 } |
|
250 --- 314,323 ---- |
|
251 { |
|
252 pat++; |
|
253 + bracklen++; |
|
254 if (*pat == ']') /* right bracket can appear as collating symbol */ |
|
255 ! { |
|
256 ! pat++; |
|
257 ! bracklen++; |
|
258 ! } |
|
259 in_collsym = 1; |
|
260 } |
|
261 *************** |
|
262 *** 290,293 **** |
|
263 --- 325,329 ---- |
|
264 { |
|
265 pat++; |
|
266 + bracklen++; |
|
267 in_collsym = 0; |
|
268 } |
|
269 *************** |
|
270 *** 295,300 **** |
|
271 { |
|
272 pat++; |
|
273 if (*pat == ']') /* right bracket can appear as equivalence class */ |
|
274 ! pat++; |
|
275 in_equiv = 1; |
|
276 } |
|
277 --- 331,340 ---- |
|
278 { |
|
279 pat++; |
|
280 + bracklen++; |
|
281 if (*pat == ']') /* right bracket can appear as equivalence class */ |
|
282 ! { |
|
283 ! pat++; |
|
284 ! bracklen++; |
|
285 ! } |
|
286 in_equiv = 1; |
|
287 } |
|
288 *************** |
|
289 *** 302,310 **** |
|
290 --- 342,354 ---- |
|
291 { |
|
292 pat++; |
|
293 + bracklen++; |
|
294 in_equiv = 0; |
|
295 } |
|
296 + else |
|
297 + bracklen++; |
|
298 } |
|
299 while ((c = *pat++) != ']'); |
|
300 matlen++; /* bracket expression can only match one char */ |
|
301 + bad_bracket: |
|
302 break; |
|
303 } |
|
304 *** ../bash-4.2-patched/patchlevel.h Sat Jun 12 20:14:48 2010 |
|
305 --- patchlevel.h Thu Feb 24 21:41:34 2011 |
|
306 *************** |
|
307 *** 26,30 **** |
|
308 looks for to find the patch level (for the sccs version string). */ |
|
309 |
|
310 ! #define PATCHLEVEL 2 |
|
311 |
|
312 #endif /* _PATCHLEVEL_H_ */ |
|
313 --- 26,30 ---- |
|
314 looks for to find the patch level (for the sccs version string). */ |
|
315 |
|
316 ! #define PATCHLEVEL 3 |
|
317 |
|
318 #endif /* _PATCHLEVEL_H_ */ |