chiark / gitweb /
Disable all exported shell functions
[bash.git] / debian / patches / bash42-003.diff
1 # DP: bash-4.2 upstream patch 003
2
3                              BASH PATCH REPORT
4                              =================
5
6 Bash-Release:   4.2
7 Patch-ID:       bash42-003
8
9 Bug-Reported-by:        Clark J. Wang <dearvoid@gmail.com>
10 Bug-Reference-ID:       <AANLkTikZ_rVV-frR8Fh0PzhXnMKnm5XsUR-F3qtPPs5G@mail.gmail.com>
11 Bug-Reference-URL:      http://lists.gnu.org/archive/html/bug-bash/2011-02/msg00136.html
12
13 Bug-Description:
14
15 When using the pattern replacement and pattern removal word expansions, bash
16 miscalculates the possible match length in the presence of an unescaped left
17 bracket without a closing right bracket, resulting in a failure to match
18 the pattern.
19
20 Patch (apply with `patch -p0'):
21
22 --- a/bash/lib/glob/gmisc.c
23 +++ b/bash/lib/glob/gmisc.c
24 @@ -77,8 +77,8 @@
25       wchar_t *wpat;
26       size_t wmax;
27  {
28 -  wchar_t wc, *wbrack;
29 -  int matlen, t, in_cclass, in_collsym, in_equiv;
30 +  wchar_t wc;
31 +  int matlen, bracklen, t, in_cclass, in_collsym, in_equiv;
32  
33    if (*wpat == 0)
34      return (0);
35 @@ -118,58 +118,80 @@
36           break;
37         case L'[':
38           /* scan for ending `]', skipping over embedded [:...:] */
39 -         wbrack = wpat;
40 +         bracklen = 1;
41           wc = *wpat++;
42           do
43             {
44               if (wc == 0)
45                 {
46 -                 matlen += wpat - wbrack - 1;  /* incremented below */
47 -                 break;
48 +                 wpat--;                       /* back up to NUL */
49 +                 matlen += bracklen;
50 +                 goto bad_bracket;
51                 }
52               else if (wc == L'\\')
53                 {
54 -                 wc = *wpat++;
55 -                 if (*wpat == 0)
56 -                   break;
57 +                 /* *wpat == backslash-escaped character */
58 +                 bracklen++;
59 +                 /* If the backslash or backslash-escape ends the string,
60 +                    bail.  The ++wpat skips over the backslash escape */
61 +                 if (*wpat == 0 || *++wpat == 0)
62 +                   {
63 +                     matlen += bracklen;
64 +                     goto bad_bracket;
65 +                   }
66                 }
67               else if (wc == L'[' && *wpat == L':')     /* character class */
68                 {
69                   wpat++;
70 +                 bracklen++;
71                   in_cclass = 1;
72                 }
73               else if (in_cclass && wc == L':' && *wpat == L']')
74                 {
75                   wpat++;
76 +                 bracklen++;
77                   in_cclass = 0;
78                 }
79               else if (wc == L'[' && *wpat == L'.')     /* collating symbol */
80                 {
81                   wpat++;
82 +                 bracklen++;
83                   if (*wpat == L']')    /* right bracket can appear as collating symbol */
84 -                   wpat++;
85 +                   {
86 +                     wpat++;
87 +                     bracklen++;
88 +                   }
89                   in_collsym = 1;
90                 }
91               else if (in_collsym && wc == L'.' && *wpat == L']')
92                 {
93                   wpat++;
94 +                 bracklen++;
95                   in_collsym = 0;
96                 }
97               else if (wc == L'[' && *wpat == L'=')     /* equivalence class */
98                 {
99                   wpat++;
100 +                 bracklen++;
101                   if (*wpat == L']')    /* right bracket can appear as equivalence class */
102 -                   wpat++;
103 +                   {
104 +                     wpat++;
105 +                     bracklen++;
106 +                   }
107                   in_equiv = 1;
108                 }
109               else if (in_equiv && wc == L'=' && *wpat == L']')
110                 {
111                   wpat++;
112 +                 bracklen++;
113                   in_equiv = 0;
114                 }
115 +             else
116 +               bracklen++;
117             }
118           while ((wc = *wpat++) != L']');
119           matlen++;             /* bracket expression can only match one char */
120 +bad_bracket:
121           break;
122         }
123      }
124 @@ -213,8 +235,8 @@
125       char *pat;
126       size_t max;
127  {
128 -  char c, *brack;
129 -  int matlen, t, in_cclass, in_collsym, in_equiv;
130 +  char c;
131 +  int matlen, bracklen, t, in_cclass, in_collsym, in_equiv;
132  
133    if (*pat == 0)
134      return (0);
135 @@ -254,58 +276,80 @@
136           break;
137         case '[':
138           /* scan for ending `]', skipping over embedded [:...:] */
139 -         brack = pat;
140 +         bracklen = 1;
141           c = *pat++;
142           do
143             {
144               if (c == 0)
145                 {
146 -                 matlen += pat - brack - 1;    /* incremented below */
147 -                 break;
148 +                 pat--;                        /* back up to NUL */
149 +                 matlen += bracklen;
150 +                 goto bad_bracket;
151                 }
152               else if (c == '\\')
153                 {
154 -                 c = *pat++;
155 -                 if (*pat == 0)
156 -                   break;
157 +                 /* *pat == backslash-escaped character */
158 +                 bracklen++;
159 +                 /* If the backslash or backslash-escape ends the string,
160 +                    bail.  The ++pat skips over the backslash escape */
161 +                 if (*pat == 0 || *++pat == 0)
162 +                   {
163 +                     matlen += bracklen;
164 +                     goto bad_bracket;
165 +                   }
166                 }
167               else if (c == '[' && *pat == ':') /* character class */
168                 {
169                   pat++;
170 +                 bracklen++;
171                   in_cclass = 1;
172                 }
173               else if (in_cclass && c == ':' && *pat == ']')
174                 {
175                   pat++;
176 +                 bracklen++;
177                   in_cclass = 0;
178                 }
179               else if (c == '[' && *pat == '.') /* collating symbol */
180                 {
181                   pat++;
182 +                 bracklen++;
183                   if (*pat == ']')      /* right bracket can appear as collating symbol */
184 -                   pat++;
185 +                   {
186 +                     pat++;
187 +                     bracklen++;
188 +                   }
189                   in_collsym = 1;
190                 }
191               else if (in_collsym && c == '.' && *pat == ']')
192                 {
193                   pat++;
194 +                 bracklen++;
195                   in_collsym = 0;
196                 }
197               else if (c == '[' && *pat == '=') /* equivalence class */
198                 {
199                   pat++;
200 +                 bracklen++;
201                   if (*pat == ']')      /* right bracket can appear as equivalence class */
202 -                   pat++;
203 +                   {
204 +                     pat++;
205 +                     bracklen++;
206 +                   }
207                   in_equiv = 1;
208                 }
209               else if (in_equiv && c == '=' && *pat == ']')
210                 {
211                   pat++;
212 +                 bracklen++;
213                   in_equiv = 0;
214                 }
215 +             else
216 +               bracklen++;
217             }
218           while ((c = *pat++) != ']');
219           matlen++;             /* bracket expression can only match one char */
220 +bad_bracket:
221           break;
222         }
223      }
224 --- a/bash/patchlevel.h
225 +++ b/bash/patchlevel.h
226 @@ -25,6 +25,6 @@
227     regexp `^#define[   ]*PATCHLEVEL', since that's what support/mkversion.sh
228     looks for to find the patch level (for the sccs version string). */
229  
230 -#define PATCHLEVEL 2
231 +#define PATCHLEVEL 3
232  
233  #endif /* _PATCHLEVEL_H_ */