7 Bug-Reported-by: Clark J. Wang <dearvoid@gmail.com>
8 Bug-Reference-ID: <AANLkTikZ_rVV-frR8Fh0PzhXnMKnm5XsUR-F3qtPPs5G@mail.gmail.com>
9 Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2011-02/msg00136.html
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
18 Patch (apply with `patch -p0'):
20 --- a/lib/glob/gmisc.c
21 +++ b/lib/glob/gmisc.c
22 @@ -77,8 +77,8 @@ wmatchlen (wpat, wmax)
26 - wchar_t wc, *wbrack;
27 - int matlen, t, in_cclass, in_collsym, in_equiv;
29 + int matlen, bracklen, t, in_cclass, in_collsym, in_equiv;
33 @@ -118,58 +118,80 @@ wmatchlen (wpat, wmax)
36 /* scan for ending `]', skipping over embedded [:...:] */
44 - matlen += wpat - wbrack - 1; /* incremented below */
46 + wpat--; /* back up to NUL */
55 + /* *wpat == backslash-escaped character */
57 + /* If the backslash or backslash-escape ends the string,
58 + bail. The ++wpat skips over the backslash escape */
59 + if (*wpat == 0 || *++wpat == 0)
65 else if (wc == L'[' && *wpat == L':') /* character class */
71 else if (in_cclass && wc == L':' && *wpat == L']')
77 else if (wc == L'[' && *wpat == L'.') /* collating symbol */
81 if (*wpat == L']') /* right bracket can appear as collating symbol */
89 else if (in_collsym && wc == L'.' && *wpat == L']')
95 else if (wc == L'[' && *wpat == L'=') /* equivalence class */
99 if (*wpat == L']') /* right bracket can appear as equivalence class */
107 else if (in_equiv && wc == L'=' && *wpat == L']')
116 while ((wc = *wpat++) != L']');
117 matlen++; /* bracket expression can only match one char */
122 @@ -213,8 +235,8 @@ umatchlen (pat, max)
127 - int matlen, t, in_cclass, in_collsym, in_equiv;
129 + int matlen, bracklen, t, in_cclass, in_collsym, in_equiv;
133 @@ -254,58 +276,80 @@ umatchlen (pat, max)
136 /* scan for ending `]', skipping over embedded [:...:] */
144 - matlen += pat - brack - 1; /* incremented below */
146 + pat--; /* back up to NUL */
147 + matlen += bracklen;
155 + /* *pat == backslash-escaped character */
157 + /* If the backslash or backslash-escape ends the string,
158 + bail. The ++pat skips over the backslash escape */
159 + if (*pat == 0 || *++pat == 0)
161 + matlen += bracklen;
165 else if (c == '[' && *pat == ':') /* character class */
171 else if (in_cclass && c == ':' && *pat == ']')
177 else if (c == '[' && *pat == '.') /* collating symbol */
181 if (*pat == ']') /* right bracket can appear as collating symbol */
189 else if (in_collsym && c == '.' && *pat == ']')
195 else if (c == '[' && *pat == '=') /* equivalence class */
199 if (*pat == ']') /* right bracket can appear as equivalence class */
207 else if (in_equiv && c == '=' && *pat == ']')
216 while ((c = *pat++) != ']');
217 matlen++; /* bracket expression can only match one char */
225 regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
226 looks for to find the patch level (for the sccs version string). */
228 -#define PATCHLEVEL 2
229 +#define PATCHLEVEL 3
231 #endif /* _PATCHLEVEL_H_ */