ntfsprogs: obsoleted
[packages.git] / utils / bash / patches / 103-upstream-bash42-003.patch
1                              BASH PATCH REPORT
2                              =================
3
4 Bash-Release:   4.2
5 Patch-ID:       bash42-003
6
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
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 --- a/lib/glob/gmisc.c
21 +++ b/lib/glob/gmisc.c
22 @@ -77,8 +77,8 @@ wmatchlen (wpat, wmax)
23       wchar_t *wpat;
24       size_t wmax;
25  {
26 -  wchar_t wc, *wbrack;
27 -  int matlen, t, in_cclass, in_collsym, in_equiv;
28 +  wchar_t wc;
29 +  int matlen, bracklen, t, in_cclass, in_collsym, in_equiv;
30  
31    if (*wpat == 0)
32      return (0);
33 @@ -118,58 +118,80 @@ wmatchlen (wpat, wmax)
34           break;
35         case L'[':
36           /* scan for ending `]', skipping over embedded [:...:] */
37 -         wbrack = wpat;
38 +         bracklen = 1;
39           wc = *wpat++;
40           do
41             {
42               if (wc == 0)
43                 {
44 -                 matlen += wpat - wbrack - 1;  /* incremented below */
45 -                 break;
46 +                 wpat--;                       /* back up to NUL */
47 +                 matlen += bracklen;
48 +                 goto bad_bracket;
49                 }
50               else if (wc == L'\\')
51                 {
52 -                 wc = *wpat++;
53 -                 if (*wpat == 0)
54 -                   break;
55 +                 /* *wpat == backslash-escaped character */
56 +                 bracklen++;
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)
60 +                   {
61 +                     matlen += bracklen;
62 +                     goto bad_bracket;
63 +                   }
64                 }
65               else if (wc == L'[' && *wpat == L':')     /* character class */
66                 {
67                   wpat++;
68 +                 bracklen++;
69                   in_cclass = 1;
70                 }
71               else if (in_cclass && wc == L':' && *wpat == L']')
72                 {
73                   wpat++;
74 +                 bracklen++;
75                   in_cclass = 0;
76                 }
77               else if (wc == L'[' && *wpat == L'.')     /* collating symbol */
78                 {
79                   wpat++;
80 +                 bracklen++;
81                   if (*wpat == L']')    /* right bracket can appear as collating symbol */
82 -                   wpat++;
83 +                   {
84 +                     wpat++;
85 +                     bracklen++;
86 +                   }
87                   in_collsym = 1;
88                 }
89               else if (in_collsym && wc == L'.' && *wpat == L']')
90                 {
91                   wpat++;
92 +                 bracklen++;
93                   in_collsym = 0;
94                 }
95               else if (wc == L'[' && *wpat == L'=')     /* equivalence class */
96                 {
97                   wpat++;
98 +                 bracklen++;
99                   if (*wpat == L']')    /* right bracket can appear as equivalence class */
100 -                   wpat++;
101 +                   {
102 +                     wpat++;
103 +                     bracklen++;
104 +                   }
105                   in_equiv = 1;
106                 }
107               else if (in_equiv && wc == L'=' && *wpat == L']')
108                 {
109                   wpat++;
110 +                 bracklen++;
111                   in_equiv = 0;
112                 }
113 +             else
114 +               bracklen++;
115             }
116           while ((wc = *wpat++) != L']');
117           matlen++;             /* bracket expression can only match one char */
118 +bad_bracket:
119           break;
120         }
121      }
122 @@ -213,8 +235,8 @@ umatchlen (pat, max)
123       char *pat;
124       size_t max;
125  {
126 -  char c, *brack;
127 -  int matlen, t, in_cclass, in_collsym, in_equiv;
128 +  char c;
129 +  int matlen, bracklen, t, in_cclass, in_collsym, in_equiv;
130  
131    if (*pat == 0)
132      return (0);
133 @@ -254,58 +276,80 @@ umatchlen (pat, max)
134           break;
135         case '[':
136           /* scan for ending `]', skipping over embedded [:...:] */
137 -         brack = pat;
138 +         bracklen = 1;
139           c = *pat++;
140           do
141             {
142               if (c == 0)
143                 {
144 -                 matlen += pat - brack - 1;    /* incremented below */
145 -                 break;
146 +                 pat--;                        /* back up to NUL */
147 +                 matlen += bracklen;
148 +                 goto bad_bracket;
149                 }
150               else if (c == '\\')
151                 {
152 -                 c = *pat++;
153 -                 if (*pat == 0)
154 -                   break;
155 +                 /* *pat == backslash-escaped character */
156 +                 bracklen++;
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)
160 +                   {
161 +                     matlen += bracklen;
162 +                     goto bad_bracket;
163 +                   }
164                 }
165               else if (c == '[' && *pat == ':') /* character class */
166                 {
167                   pat++;
168 +                 bracklen++;
169                   in_cclass = 1;
170                 }
171               else if (in_cclass && c == ':' && *pat == ']')
172                 {
173                   pat++;
174 +                 bracklen++;
175                   in_cclass = 0;
176                 }
177               else if (c == '[' && *pat == '.') /* collating symbol */
178                 {
179                   pat++;
180 +                 bracklen++;
181                   if (*pat == ']')      /* right bracket can appear as collating symbol */
182 -                   pat++;
183 +                   {
184 +                     pat++;
185 +                     bracklen++;
186 +                   }
187                   in_collsym = 1;
188                 }
189               else if (in_collsym && c == '.' && *pat == ']')
190                 {
191                   pat++;
192 +                 bracklen++;
193                   in_collsym = 0;
194                 }
195               else if (c == '[' && *pat == '=') /* equivalence class */
196                 {
197                   pat++;
198 +                 bracklen++;
199                   if (*pat == ']')      /* right bracket can appear as equivalence class */
200 -                   pat++;
201 +                   {
202 +                     pat++;
203 +                     bracklen++;
204 +                   }
205                   in_equiv = 1;
206                 }
207               else if (in_equiv && c == '=' && *pat == ']')
208                 {
209                   pat++;
210 +                 bracklen++;
211                   in_equiv = 0;
212                 }
213 +             else
214 +               bracklen++;
215             }
216           while ((c = *pat++) != ']');
217           matlen++;             /* bracket expression can only match one char */
218 +bad_bracket:
219           break;
220         }
221      }
222 --- a/patchlevel.h
223 +++ b/patchlevel.h
224 @@ -25,6 +25,6 @@
225     regexp `^#define[   ]*PATCHLEVEL', since that's what support/mkversion.sh
226     looks for to find the patch level (for the sccs version string). */
227  
228 -#define PATCHLEVEL 2
229 +#define PATCHLEVEL 3
230  
231  #endif /* _PATCHLEVEL_H_ */