]>
Commit | Line | Data |
---|---|---|
404c5eba ER |
1 | BASH PATCH REPORT |
2 | ================= | |
3 | ||
4 | Bash-Release: 3.2 | |
5 | Patch-ID: bash32-003 | |
6 | ||
7 | Bug-Reported-by: John Gatewood Ham <zappaman@buraphalinux.org> | |
8 | Bug-Reference-ID: <Pine.LNX.4.64.0610121334140.15558@www.buraphalinux.org> | |
9 | Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2006-10/msg00045.html | |
10 | ||
11 | Bug-Description: | |
12 | ||
13 | When using the conditional command's `=~' operator to match regular | |
14 | expressions, the parser did not skip over shell metacharacters in the | |
15 | regular expression, leading to syntax errors. | |
16 | ||
17 | Patch: | |
18 | ||
19 | *** ../bash-3.2-patched/parse.y Tue Oct 17 11:45:20 2006 | |
20 | --- parse.y Sat Oct 14 14:56:16 2006 | |
21 | *************** | |
22 | *** 1029,1034 **** | |
23 | --- 1029,1035 ---- | |
24 | #define PST_CMDTOKEN 0x1000 /* command token OK - unused */ | |
25 | #define PST_COMPASSIGN 0x2000 /* parsing x=(...) compound assignment */ | |
26 | #define PST_ASSIGNOK 0x4000 /* assignment statement ok in this context */ | |
27 | + #define PST_REGEXP 0x8000 /* parsing an ERE/BRE as a single word */ | |
28 | ||
29 | /* Initial size to allocate for tokens, and the | |
30 | amount to grow them by. */ | |
31 | *************** | |
32 | *** 2591,2596 **** | |
33 | --- 2592,2600 ---- | |
34 | return (character); | |
35 | } | |
36 | ||
37 | + if (parser_state & PST_REGEXP) | |
38 | + goto tokword; | |
39 | + | |
40 | /* Shell meta-characters. */ | |
41 | if MBTEST(shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0)) | |
42 | { | |
43 | *************** | |
44 | *** 2698,2703 **** | |
45 | --- 2702,2708 ---- | |
46 | if MBTEST(character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND)) | |
47 | return (character); | |
48 | ||
49 | + tokword: | |
50 | /* Okay, if we got this far, we have to read a word. Read one, | |
51 | and then check it against the known ones. */ | |
52 | result = read_token_word (character); | |
53 | *************** | |
54 | *** 3202,3209 **** | |
55 | if (tok == WORD && test_binop (yylval.word->word)) | |
56 | op = yylval.word; | |
57 | #if defined (COND_REGEXP) | |
58 | ! else if (tok == WORD && STREQ (yylval.word->word,"=~")) | |
59 | ! op = yylval.word; | |
60 | #endif | |
61 | else if (tok == '<' || tok == '>') | |
62 | op = make_word_from_token (tok); /* ( */ | |
63 | --- 3207,3217 ---- | |
64 | if (tok == WORD && test_binop (yylval.word->word)) | |
65 | op = yylval.word; | |
66 | #if defined (COND_REGEXP) | |
67 | ! else if (tok == WORD && STREQ (yylval.word->word, "=~")) | |
68 | ! { | |
69 | ! op = yylval.word; | |
70 | ! parser_state |= PST_REGEXP; | |
71 | ! } | |
72 | #endif | |
73 | else if (tok == '<' || tok == '>') | |
74 | op = make_word_from_token (tok); /* ( */ | |
75 | *************** | |
76 | *** 3234,3239 **** | |
77 | --- 3242,3248 ---- | |
78 | ||
79 | /* rhs */ | |
80 | tok = read_token (READ); | |
81 | + parser_state &= ~PST_REGEXP; | |
82 | if (tok == WORD) | |
83 | { | |
84 | tright = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL); | |
85 | *************** | |
86 | *** 3419,3427 **** | |
87 | goto next_character; | |
88 | } | |
89 | ||
90 | #ifdef EXTENDED_GLOB | |
91 | /* Parse a ksh-style extended pattern matching specification. */ | |
92 | ! if (extended_glob && PATTERN_CHAR (character)) | |
93 | { | |
94 | peek_char = shell_getc (1); | |
95 | if MBTEST(peek_char == '(') /* ) */ | |
96 | --- 3428,3461 ---- | |
97 | goto next_character; | |
98 | } | |
99 | ||
100 | + #ifdef COND_REGEXP | |
101 | + /* When parsing a regexp as a single word inside a conditional command, | |
102 | + we need to special-case characters special to both the shell and | |
103 | + regular expressions. Right now, that is only '(' and '|'. */ /*)*/ | |
104 | + if MBTEST((parser_state & PST_REGEXP) && (character == '(' || character == '|')) /*)*/ | |
105 | + { | |
106 | + if (character == '|') | |
107 | + goto got_character; | |
108 | + | |
109 | + push_delimiter (dstack, character); | |
110 | + ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0); | |
111 | + pop_delimiter (dstack); | |
112 | + if (ttok == &matched_pair_error) | |
113 | + return -1; /* Bail immediately. */ | |
114 | + RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2, | |
115 | + token_buffer_size, TOKEN_DEFAULT_GROW_SIZE); | |
116 | + token[token_index++] = character; | |
117 | + strcpy (token + token_index, ttok); | |
118 | + token_index += ttoklen; | |
119 | + FREE (ttok); | |
120 | + dollar_present = all_digit_token = 0; | |
121 | + goto next_character; | |
122 | + } | |
123 | + #endif /* COND_REGEXP */ | |
124 | + | |
125 | #ifdef EXTENDED_GLOB | |
126 | /* Parse a ksh-style extended pattern matching specification. */ | |
127 | ! if MBTEST(extended_glob && PATTERN_CHAR (character)) | |
128 | { | |
129 | peek_char = shell_getc (1); | |
130 | if MBTEST(peek_char == '(') /* ) */ | |
131 | ||
132 | *** ../bash-3.2/patchlevel.h Thu Apr 13 08:31:04 2006 | |
133 | --- patchlevel.h Mon Oct 16 14:22:54 2006 | |
134 | *************** | |
135 | *** 26,30 **** | |
136 | looks for to find the patch level (for the sccs version string). */ | |
137 | ||
138 | ! #define PATCHLEVEL 2 | |
139 | ||
140 | #endif /* _PATCHLEVEL_H_ */ | |
141 | --- 26,30 ---- | |
142 | looks for to find the patch level (for the sccs version string). */ | |
143 | ||
144 | ! #define PATCHLEVEL 3 | |
145 | ||
146 | #endif /* _PATCHLEVEL_H_ */ | |
147 |