diff options
author | Erik Andersen <andersen@codepoet.org> | 2000-03-06 19:20:35 +0000 |
---|---|---|
committer | Erik Andersen <andersen@codepoet.org> | 2000-03-06 19:20:35 +0000 |
commit | e916d24805b4a191bc08d2ee31c9247a30f9bc1e (patch) | |
tree | ac14b799b56d16ae84ff3960f59dc3ede01bc0a1 | |
parent | 9c5c29d442d588ffce390e18fc554f258f6d523e (diff) | |
download | busybox-w32-e916d24805b4a191bc08d2ee31c9247a30f9bc1e.tar.gz busybox-w32-e916d24805b4a191bc08d2ee31c9247a30f9bc1e.tar.bz2 busybox-w32-e916d24805b4a191bc08d2ee31c9247a30f9bc1e.zip |
Fixed a bug where "sed 's/foo/bar/g'" (i.e. a script w/o a -e)
would go into an infinite loop.
-Erik
-rw-r--r-- | Changelog | 2 | ||||
-rw-r--r-- | editors/sed.c | 246 | ||||
-rw-r--r-- | sed.c | 246 |
3 files changed, 248 insertions, 246 deletions
@@ -35,6 +35,8 @@ | |||
35 | - Fixes to the makefile for handling "strip" | 35 | - Fixes to the makefile for handling "strip" |
36 | * An initial telnet implementation was added by | 36 | * An initial telnet implementation was added by |
37 | Randolph Chung <tausq@debian.org>. | 37 | Randolph Chung <tausq@debian.org>. |
38 | * Fixed a bug where "sed 's/foo/bar/g'" would go into an | ||
39 | infinite loop. | ||
38 | 40 | ||
39 | 41 | ||
40 | -Erik Andersen | 42 | -Erik Andersen |
diff --git a/editors/sed.c b/editors/sed.c index 608f86813..2beb2a588 100644 --- a/editors/sed.c +++ b/editors/sed.c | |||
@@ -184,129 +184,129 @@ extern int sed_main(int argc, char **argv) | |||
184 | } | 184 | } |
185 | 185 | ||
186 | while (argc > 1) { | 186 | while (argc > 1) { |
187 | if (**argv == '-') { | 187 | if (**argv != '-') |
188 | argc--; | 188 | usage(sed_usage); |
189 | cp = *argv++; | 189 | argc--; |
190 | stopNow = FALSE; | 190 | cp = *argv++; |
191 | 191 | stopNow = FALSE; | |
192 | while (*++cp && stopNow == FALSE) { | 192 | |
193 | switch (*cp) { | 193 | while (*++cp && stopNow == FALSE) { |
194 | case 'n': | 194 | switch (*cp) { |
195 | quietFlag = TRUE; | 195 | case 'n': |
196 | break; | 196 | quietFlag = TRUE; |
197 | case 'e': | 197 | break; |
198 | if (*(cp + 1) == 0 && --argc < 0) { | 198 | case 'e': |
199 | usage(sed_usage); | 199 | if (*(cp + 1) == 0 && --argc < 0) { |
200 | } | 200 | usage(sed_usage); |
201 | if (*++cp != 's') | 201 | } |
202 | cp = *argv++; | 202 | if (*++cp != 's') |
203 | 203 | cp = *argv++; | |
204 | /* Read address if present */ | 204 | |
205 | SKIPSPACES(cp); | 205 | /* Read address if present */ |
206 | if (*cp == '$') { | 206 | SKIPSPACES(cp); |
207 | addr_line = LAST_LINE; | 207 | if (*cp == '$') { |
208 | cp++; | 208 | addr_line = LAST_LINE; |
209 | } else { | 209 | cp++; |
210 | if (isdigit(*cp)) { /* LINE ADDRESS */ | 210 | } else { |
211 | line_s = cp; | 211 | if (isdigit(*cp)) { /* LINE ADDRESS */ |
212 | while (isdigit(*cp)) | 212 | line_s = cp; |
213 | cp++; | 213 | while (isdigit(*cp)) |
214 | if (cp > line_s) { | 214 | cp++; |
215 | /* numeric line */ | 215 | if (cp > line_s) { |
216 | saved = *cp; | 216 | /* numeric line */ |
217 | *cp = '\0'; | 217 | saved = *cp; |
218 | addr_line = atoi(line_s); | 218 | *cp = '\0'; |
219 | *cp = saved; | 219 | addr_line = atoi(line_s); |
220 | } | 220 | *cp = saved; |
221 | } else if (*cp == '/') { /* PATTERN ADDRESS */ | 221 | } |
222 | pos = addr_pattern = cp + 1; | 222 | } else if (*cp == '/') { /* PATTERN ADDRESS */ |
223 | pos = strchr(pos, '/'); | 223 | pos = addr_pattern = cp + 1; |
224 | if (!pos) | 224 | pos = strchr(pos, '/'); |
225 | usage(sed_usage); | 225 | if (!pos) |
226 | *pos = '\0'; | 226 | usage(sed_usage); |
227 | cp = pos + 1; | 227 | *pos = '\0'; |
228 | } | 228 | cp = pos + 1; |
229 | } | 229 | } |
230 | 230 | } | |
231 | SKIPSPACES(cp); | 231 | |
232 | if (*cp == '!') { | 232 | SKIPSPACES(cp); |
233 | negated++; | 233 | if (*cp == '!') { |
234 | cp++; | 234 | negated++; |
235 | } | 235 | cp++; |
236 | 236 | } | |
237 | /* Read command */ | 237 | |
238 | 238 | /* Read command */ | |
239 | SKIPSPACES(cp); | 239 | |
240 | switch (*cp) { | 240 | SKIPSPACES(cp); |
241 | case 's': /* REPLACE */ | 241 | switch (*cp) { |
242 | if (strlen(cp) <= 3 || *(cp + 1) != '/') | 242 | case 's': /* REPLACE */ |
243 | break; | 243 | if (strlen(cp) <= 3 || *(cp + 1) != '/') |
244 | sed_f = f_replace; | 244 | break; |
245 | 245 | sed_f = f_replace; | |
246 | pos = needle = cp + 2; | 246 | |
247 | 247 | pos = needle = cp + 2; | |
248 | for (;;) { | 248 | |
249 | pos = strchr(pos, '/'); | 249 | for (;;) { |
250 | if (pos == NULL) { | 250 | pos = strchr(pos, '/'); |
251 | usage(sed_usage); | 251 | if (pos == NULL) { |
252 | } | 252 | usage(sed_usage); |
253 | if (*(pos - 1) == '\\') { | 253 | } |
254 | pos++; | 254 | if (*(pos - 1) == '\\') { |
255 | continue; | 255 | pos++; |
256 | } | 256 | continue; |
257 | break; | 257 | } |
258 | } | 258 | break; |
259 | *pos = 0; | 259 | } |
260 | newNeedle = ++pos; | 260 | *pos = 0; |
261 | for (;;) { | 261 | newNeedle = ++pos; |
262 | pos = strchr(pos, '/'); | 262 | for (;;) { |
263 | if (pos == NULL) { | 263 | pos = strchr(pos, '/'); |
264 | usage(sed_usage); | 264 | if (pos == NULL) { |
265 | } | 265 | usage(sed_usage); |
266 | if (*(pos - 1) == '\\') { | 266 | } |
267 | pos++; | 267 | if (*(pos - 1) == '\\') { |
268 | continue; | 268 | pos++; |
269 | } | 269 | continue; |
270 | break; | 270 | } |
271 | } | 271 | break; |
272 | *pos = 0; | 272 | } |
273 | if (pos + 2 != 0) { | 273 | *pos = 0; |
274 | while (*++pos) { | 274 | if (pos + 2 != 0) { |
275 | switch (*pos) { | 275 | while (*++pos) { |
276 | case 'i': | 276 | switch (*pos) { |
277 | ignoreCase = TRUE; | 277 | case 'i': |
278 | break; | 278 | ignoreCase = TRUE; |
279 | case 'p': | 279 | break; |
280 | printFlag = TRUE; | 280 | case 'p': |
281 | break; | 281 | printFlag = TRUE; |
282 | case 'g': | 282 | break; |
283 | break; | 283 | case 'g': |
284 | default: | 284 | break; |
285 | usage(sed_usage); | 285 | default: |
286 | } | 286 | usage(sed_usage); |
287 | } | 287 | } |
288 | } | 288 | } |
289 | cp = pos; | 289 | } |
290 | /* fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); */ | 290 | cp = pos; |
291 | break; | 291 | /* fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); */ |
292 | 292 | break; | |
293 | case 'a': /* APPEND */ | 293 | |
294 | if (strlen(cp) < 2) | 294 | case 'a': /* APPEND */ |
295 | break; | 295 | if (strlen(cp) < 2) |
296 | sed_f = f_append; | 296 | break; |
297 | appendline = ++cp; | 297 | sed_f = f_append; |
298 | /* fprintf(stderr, "append '%s'\n", appendline); */ | 298 | appendline = ++cp; |
299 | break; | 299 | /* fprintf(stderr, "append '%s'\n", appendline); */ |
300 | } | 300 | break; |
301 | 301 | } | |
302 | stopNow = TRUE; | 302 | |
303 | break; | 303 | stopNow = TRUE; |
304 | 304 | break; | |
305 | default: | 305 | |
306 | usage(sed_usage); | 306 | default: |
307 | } | 307 | usage(sed_usage); |
308 | } | 308 | } |
309 | } | 309 | } |
310 | } | 310 | } |
311 | 311 | ||
312 | if (argc == 0) { | 312 | if (argc == 0) { |
@@ -184,129 +184,129 @@ extern int sed_main(int argc, char **argv) | |||
184 | } | 184 | } |
185 | 185 | ||
186 | while (argc > 1) { | 186 | while (argc > 1) { |
187 | if (**argv == '-') { | 187 | if (**argv != '-') |
188 | argc--; | 188 | usage(sed_usage); |
189 | cp = *argv++; | 189 | argc--; |
190 | stopNow = FALSE; | 190 | cp = *argv++; |
191 | 191 | stopNow = FALSE; | |
192 | while (*++cp && stopNow == FALSE) { | 192 | |
193 | switch (*cp) { | 193 | while (*++cp && stopNow == FALSE) { |
194 | case 'n': | 194 | switch (*cp) { |
195 | quietFlag = TRUE; | 195 | case 'n': |
196 | break; | 196 | quietFlag = TRUE; |
197 | case 'e': | 197 | break; |
198 | if (*(cp + 1) == 0 && --argc < 0) { | 198 | case 'e': |
199 | usage(sed_usage); | 199 | if (*(cp + 1) == 0 && --argc < 0) { |
200 | } | 200 | usage(sed_usage); |
201 | if (*++cp != 's') | 201 | } |
202 | cp = *argv++; | 202 | if (*++cp != 's') |
203 | 203 | cp = *argv++; | |
204 | /* Read address if present */ | 204 | |
205 | SKIPSPACES(cp); | 205 | /* Read address if present */ |
206 | if (*cp == '$') { | 206 | SKIPSPACES(cp); |
207 | addr_line = LAST_LINE; | 207 | if (*cp == '$') { |
208 | cp++; | 208 | addr_line = LAST_LINE; |
209 | } else { | 209 | cp++; |
210 | if (isdigit(*cp)) { /* LINE ADDRESS */ | 210 | } else { |
211 | line_s = cp; | 211 | if (isdigit(*cp)) { /* LINE ADDRESS */ |
212 | while (isdigit(*cp)) | 212 | line_s = cp; |
213 | cp++; | 213 | while (isdigit(*cp)) |
214 | if (cp > line_s) { | 214 | cp++; |
215 | /* numeric line */ | 215 | if (cp > line_s) { |
216 | saved = *cp; | 216 | /* numeric line */ |
217 | *cp = '\0'; | 217 | saved = *cp; |
218 | addr_line = atoi(line_s); | 218 | *cp = '\0'; |
219 | *cp = saved; | 219 | addr_line = atoi(line_s); |
220 | } | 220 | *cp = saved; |
221 | } else if (*cp == '/') { /* PATTERN ADDRESS */ | 221 | } |
222 | pos = addr_pattern = cp + 1; | 222 | } else if (*cp == '/') { /* PATTERN ADDRESS */ |
223 | pos = strchr(pos, '/'); | 223 | pos = addr_pattern = cp + 1; |
224 | if (!pos) | 224 | pos = strchr(pos, '/'); |
225 | usage(sed_usage); | 225 | if (!pos) |
226 | *pos = '\0'; | 226 | usage(sed_usage); |
227 | cp = pos + 1; | 227 | *pos = '\0'; |
228 | } | 228 | cp = pos + 1; |
229 | } | 229 | } |
230 | 230 | } | |
231 | SKIPSPACES(cp); | 231 | |
232 | if (*cp == '!') { | 232 | SKIPSPACES(cp); |
233 | negated++; | 233 | if (*cp == '!') { |
234 | cp++; | 234 | negated++; |
235 | } | 235 | cp++; |
236 | 236 | } | |
237 | /* Read command */ | 237 | |
238 | 238 | /* Read command */ | |
239 | SKIPSPACES(cp); | 239 | |
240 | switch (*cp) { | 240 | SKIPSPACES(cp); |
241 | case 's': /* REPLACE */ | 241 | switch (*cp) { |
242 | if (strlen(cp) <= 3 || *(cp + 1) != '/') | 242 | case 's': /* REPLACE */ |
243 | break; | 243 | if (strlen(cp) <= 3 || *(cp + 1) != '/') |
244 | sed_f = f_replace; | 244 | break; |
245 | 245 | sed_f = f_replace; | |
246 | pos = needle = cp + 2; | 246 | |
247 | 247 | pos = needle = cp + 2; | |
248 | for (;;) { | 248 | |
249 | pos = strchr(pos, '/'); | 249 | for (;;) { |
250 | if (pos == NULL) { | 250 | pos = strchr(pos, '/'); |
251 | usage(sed_usage); | 251 | if (pos == NULL) { |
252 | } | 252 | usage(sed_usage); |
253 | if (*(pos - 1) == '\\') { | 253 | } |
254 | pos++; | 254 | if (*(pos - 1) == '\\') { |
255 | continue; | 255 | pos++; |
256 | } | 256 | continue; |
257 | break; | 257 | } |
258 | } | 258 | break; |
259 | *pos = 0; | 259 | } |
260 | newNeedle = ++pos; | 260 | *pos = 0; |
261 | for (;;) { | 261 | newNeedle = ++pos; |
262 | pos = strchr(pos, '/'); | 262 | for (;;) { |
263 | if (pos == NULL) { | 263 | pos = strchr(pos, '/'); |
264 | usage(sed_usage); | 264 | if (pos == NULL) { |
265 | } | 265 | usage(sed_usage); |
266 | if (*(pos - 1) == '\\') { | 266 | } |
267 | pos++; | 267 | if (*(pos - 1) == '\\') { |
268 | continue; | 268 | pos++; |
269 | } | 269 | continue; |
270 | break; | 270 | } |
271 | } | 271 | break; |
272 | *pos = 0; | 272 | } |
273 | if (pos + 2 != 0) { | 273 | *pos = 0; |
274 | while (*++pos) { | 274 | if (pos + 2 != 0) { |
275 | switch (*pos) { | 275 | while (*++pos) { |
276 | case 'i': | 276 | switch (*pos) { |
277 | ignoreCase = TRUE; | 277 | case 'i': |
278 | break; | 278 | ignoreCase = TRUE; |
279 | case 'p': | 279 | break; |
280 | printFlag = TRUE; | 280 | case 'p': |
281 | break; | 281 | printFlag = TRUE; |
282 | case 'g': | 282 | break; |
283 | break; | 283 | case 'g': |
284 | default: | 284 | break; |
285 | usage(sed_usage); | 285 | default: |
286 | } | 286 | usage(sed_usage); |
287 | } | 287 | } |
288 | } | 288 | } |
289 | cp = pos; | 289 | } |
290 | /* fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); */ | 290 | cp = pos; |
291 | break; | 291 | /* fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); */ |
292 | 292 | break; | |
293 | case 'a': /* APPEND */ | 293 | |
294 | if (strlen(cp) < 2) | 294 | case 'a': /* APPEND */ |
295 | break; | 295 | if (strlen(cp) < 2) |
296 | sed_f = f_append; | 296 | break; |
297 | appendline = ++cp; | 297 | sed_f = f_append; |
298 | /* fprintf(stderr, "append '%s'\n", appendline); */ | 298 | appendline = ++cp; |
299 | break; | 299 | /* fprintf(stderr, "append '%s'\n", appendline); */ |
300 | } | 300 | break; |
301 | 301 | } | |
302 | stopNow = TRUE; | 302 | |
303 | break; | 303 | stopNow = TRUE; |
304 | 304 | break; | |
305 | default: | 305 | |
306 | usage(sed_usage); | 306 | default: |
307 | } | 307 | usage(sed_usage); |
308 | } | 308 | } |
309 | } | 309 | } |
310 | } | 310 | } |
311 | 311 | ||
312 | if (argc == 0) { | 312 | if (argc == 0) { |