]> git.pld-linux.org Git - packages/bash.git/blob - bash40-007
- up to 4.0.10
[packages/bash.git] / bash40-007
1                              BASH PATCH REPORT
2                              =================
3
4 Bash-Release: 4.0
5 Patch-ID: bash40-007
6
7 Bug-Reported-by:        AnMaster <anmaster@tele2.se>
8 Bug-Reference-ID:       <49A41C18.80807@tele2.se>
9 Bug-Reference-URL:      http://lists.gnu.org/archive/html/bug-bash/2009-02/msg00188.html
10
11 Bug-Description:
12
13 Bash had a number of problems parsing associative array subscripts containing
14 special characters.  The subscripts are supposed to be read as if they are
15 enclosed between double quotes.
16
17 Patch:
18
19 *** ../bash-4.0/parse.y 2009-01-08 08:29:12.000000000 -0500
20 --- parse.y     2009-02-25 17:25:56.000000000 -0500
21 ***************
22 *** 2919,2922 ****
23 --- 2919,2923 ----
24   #define P_COMMAND     0x08    /* parsing a command, so look for comments */
25   #define P_BACKQUOTE   0x10    /* parsing a backquoted command substitution */
26 + #define P_ARRAYSUB    0x20    /* parsing a [...] array subscript for assignment */
27   
28   /* Lexical state while parsing a grouping construct or $(...). */
29 ***************
30 *** 3134,3137 ****
31 --- 3134,3139 ----
32               FREE (nestret);
33             }
34 +         else if ((flags & P_ARRAYSUB) && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '['))      /* ) } ] */
35 +           goto parse_dollar_word;
36         }
37         /* Parse an old-style command substitution within double quotes as a
38 ***************
39 *** 3150,3153 ****
40 --- 3150,3154 ----
41         /* check for $(), $[], or ${} inside quoted string. */
42         {
43 + parse_dollar_word:
44           if (open == ch)       /* undo previous increment */
45             count--;
46 ***************
47 *** 4277,4281 ****
48                       (token_index == 0 && (parser_state&PST_COMPASSIGN))))
49           {
50 !         ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
51           if (ttok == &matched_pair_error)
52             return -1;          /* Bail immediately. */
53 --- 4277,4281 ----
54                       (token_index == 0 && (parser_state&PST_COMPASSIGN))))
55           {
56 !         ttok = parse_matched_pair (cd, '[', ']', &ttoklen, P_ARRAYSUB);
57           if (ttok == &matched_pair_error)
58             return -1;          /* Bail immediately. */
59 *** ../bash-4.0/arrayfunc.c     2009-01-04 14:32:21.000000000 -0500
60 --- arrayfunc.c 2009-02-25 07:58:54.000000000 -0500
61 ***************
62 *** 605,666 ****
63   }
64   
65 ! /* This function assumes s[i] == '['; returns with s[ret] == ']' if
66 !    an array subscript is correctly parsed. */
67 ! int
68 ! skipsubscript (s, i)
69 !      const char *s;
70 !      int i;
71 ! {
72 !   int count, c;
73 ! #if defined (HANDLE_MULTIBYTE)
74 !   mbstate_t state, state_bak;
75 !   size_t slength, mblength;
76 ! #endif
77
78 ! #if defined (HANDLE_MULTIBYTE)
79 !   memset (&state, '\0', sizeof (mbstate_t));
80 !   slength = strlen (s + i);
81 ! #endif
82 !   
83 !   count = 1;
84 !   while (count)
85 !     {
86 !       /* Advance one (possibly multibyte) character in S starting at I. */
87 ! #if defined (HANDLE_MULTIBYTE)
88 !       if (MB_CUR_MAX > 1)
89 !       {
90 !         state_bak = state;
91 !         mblength = mbrlen (s + i, slength, &state);
92
93 !         if (MB_INVALIDCH (mblength))
94 !           {
95 !             state = state_bak;
96 !             i++;
97 !             slength--;
98 !           }
99 !         else if (MB_NULLWCH (mblength))
100 !           return i;
101 !         else
102 !           {
103 !             i += mblength;
104 !             slength -= mblength;
105 !           }
106 !       }
107 !       else
108 ! #endif
109 !       ++i;
110
111 !       c = s[i];
112
113 !       if (c == 0)
114 !       break;
115 !       else if (c == '[')
116 !       count++;
117 !       else if (c == ']')
118 !       count--;
119 !     }
120
121 !   return i;
122 ! }
123   
124   /* This function is called with SUB pointing to just after the beginning
125 --- 605,609 ----
126   }
127   
128 ! /* skipsubscript moved to subst.c to use private functions. 2009/02/24. */
129   
130   /* This function is called with SUB pointing to just after the beginning
131 *** ../bash-4.0/subst.c 2009-01-28 14:34:12.000000000 -0500
132 --- subst.c     2009-02-25 09:18:33.000000000 -0500
133 ***************
134 *** 223,226 ****
135 --- 223,227 ----
136   static char *extract_delimited_string __P((char *, int *, char *, char *, char *, int));
137   static char *extract_dollar_brace_string __P((char *, int *, int, int));
138 + static int skip_matched_pair __P((const char *, int, int, int, int));
139   
140   static char *pos_params __P((char *, int, int, int));
141 ***************
142 *** 1375,1378 ****
143 --- 1376,1480 ----
144   #define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0)
145   
146 + /* This function assumes s[i] == open; returns with s[ret] == close; used to
147 +    parse array subscripts.  FLAGS currently unused. */
148 + static int
149 + skip_matched_pair (string, start, open, close, flags)
150 +      const char *string;
151 +      int start, open, close, flags;
152 + {
153 +   int i, pass_next, backq, si, c, count;
154 +   size_t slen;
155 +   char *temp, *ss;
156 +   DECLARE_MBSTATE;
157
158 +   slen = strlen (string + start) + start;
159 +   no_longjmp_on_fatal_error = 1;
160
161 +   i = start + 1;              /* skip over leading bracket */
162 +   count = 1;
163 +   pass_next = backq = 0;
164 +   ss = (char *)string;
165 +   while (c = string[i])
166 +     {
167 +       if (pass_next)
168 +       {
169 +         pass_next = 0;
170 +         if (c == 0)
171 +           CQ_RETURN(i);
172 +         ADVANCE_CHAR (string, slen, i);
173 +         continue;
174 +       }
175 +       else if (c == '\\')
176 +       {
177 +         pass_next = 1;
178 +         i++;
179 +         continue;
180 +       }
181 +       else if (backq)
182 +       {
183 +         if (c == '`')
184 +           backq = 0;
185 +         ADVANCE_CHAR (string, slen, i);
186 +         continue;
187 +       }
188 +       else if (c == '`')
189 +       {
190 +         backq = 1;
191 +         i++;
192 +         continue;
193 +       }
194 +       else if (c == open)
195 +       {
196 +         count++;
197 +         i++;
198 +         continue;
199 +       }
200 +       else if (c == close)
201 +       {
202 +         count--;
203 +         if (count == 0)
204 +           break;
205 +         i++;
206 +         continue;
207 +       }
208 +       else if (c == '\'' || c == '"')
209 +       {
210 +         i = (c == '\'') ? skip_single_quoted (ss, slen, ++i)
211 +                         : skip_double_quoted (ss, slen, ++i);
212 +         /* no increment, the skip functions increment past the closing quote. */
213 +       }
214 +       else if (c == '$' && (string[i+1] == LPAREN || string[i+1] == LBRACE))
215 +       {
216 +         si = i + 2;
217 +         if (string[si] == '\0')
218 +           CQ_RETURN(si);
219
220 +         if (string[i+1] == LPAREN)
221 +           temp = extract_delimited_string (ss, &si, "$(", "(", ")", SX_NOALLOC|SX_COMMAND); /* ) */
222 +         else
223 +           temp = extract_dollar_brace_string (ss, &si, 0, SX_NOALLOC);
224 +         i = si;
225 +         if (string[i] == '\0')        /* don't increment i past EOS in loop */
226 +           break;
227 +         i++;
228 +         continue;
229 +       }
230 +       else
231 +       ADVANCE_CHAR (string, slen, i);
232 +     }
233
234 +   CQ_RETURN(i);
235 + }
236
237 + #if defined (ARRAY_VARS)
238 + int
239 + skipsubscript (string, start)
240 +      const char *string;
241 +      int start;
242 + {
243 +   return (skip_matched_pair (string, start, '[', ']', 0));
244 + }
245 + #endif
246
247   /* Skip characters in STRING until we find a character in DELIMS, and return
248      the index of that character.  START is the index into string at which we
249 *** ../bash-4.0/patchlevel.h    2009-01-04 14:32:40.000000000 -0500
250 --- patchlevel.h        2009-02-22 16:11:31.000000000 -0500
251 ***************
252 *** 26,30 ****
253      looks for to find the patch level (for the sccs version string). */
254   
255 ! #define PATCHLEVEL 6
256   
257   #endif /* _PATCHLEVEL_H_ */
258 --- 26,30 ----
259      looks for to find the patch level (for the sccs version string). */
260   
261 ! #define PATCHLEVEL 7
262   
263   #endif /* _PATCHLEVEL_H_ */
This page took 0.149663 seconds and 3 git commands to generate.