diff options
author | Mark Whitley <markw@lineo.com> | 2000-07-14 23:24:00 +0000 |
---|---|---|
committer | Mark Whitley <markw@lineo.com> | 2000-07-14 23:24:00 +0000 |
commit | 464c5de00d3dfb5f01e866f703d95bbb2bb9443c (patch) | |
tree | c770d2ac4df0293c245dc246f93abf500545d865 | |
parent | 70705d7c9681b4ea870ea11d0c569d81e5822169 (diff) | |
download | busybox-w32-464c5de00d3dfb5f01e866f703d95bbb2bb9443c.tar.gz busybox-w32-464c5de00d3dfb5f01e866f703d95bbb2bb9443c.tar.bz2 busybox-w32-464c5de00d3dfb5f01e866f703d95bbb2bb9443c.zip |
Fixed a couple of buglets:
- add_cmd_str: segv's were being generated if there was a '# comment' line
(and probably other kinds of lines, too) that was not followed by a
semi-colon or whitespace
- parse_edit_cmd: was returning a wrong number (too low) for the index; it
was not accounting for backslashes eaten, for the fact that we start at the
3rd index in the string, or for the fact that we add an extra newline.
- parse_cmd_str: was returning a wrong number (again, too low) for the index
in the case of single-letter commands (p,d). There was some
over-compensation for this in the 'return' stmt at the end which also
needed some help.
- load_cmd_file: was not eating trailing newlines off the line read from the
command file. This had the deleterious effect of printing an extra newlines
after text displayed from edit (i,a,c) commands.
-rw-r--r-- | editors/sed.c | 35 | ||||
-rw-r--r-- | sed.c | 35 |
2 files changed, 58 insertions, 12 deletions
diff --git a/editors/sed.c b/editors/sed.c index 40400fe3a..1f1e9069c 100644 --- a/editors/sed.c +++ b/editors/sed.c | |||
@@ -307,6 +307,7 @@ out: | |||
307 | static int parse_edit_cmd(struct sed_cmd *sed_cmd, const char *editstr) | 307 | static int parse_edit_cmd(struct sed_cmd *sed_cmd, const char *editstr) |
308 | { | 308 | { |
309 | int idx = 0; | 309 | int idx = 0; |
310 | int slashes_eaten = 0; | ||
310 | char *ptr; /* shorthand */ | 311 | char *ptr; /* shorthand */ |
311 | 312 | ||
312 | /* | 313 | /* |
@@ -346,19 +347,32 @@ static int parse_edit_cmd(struct sed_cmd *sed_cmd, const char *editstr) | |||
346 | while (ptr[idx] != '\\' && (ptr[idx+1] != '\n' || ptr[idx+1] != '\r')) { | 347 | while (ptr[idx] != '\\' && (ptr[idx+1] != '\n' || ptr[idx+1] != '\r')) { |
347 | idx++; | 348 | idx++; |
348 | if (!ptr[idx]) { | 349 | if (!ptr[idx]) { |
349 | ptr[idx] = '\n'; | 350 | goto out; |
350 | ptr[idx+1] = 0; | ||
351 | return idx; | ||
352 | } | 351 | } |
353 | } | 352 | } |
354 | /* move the newline over the '\' before it (effectively eats the '\') */ | 353 | /* move the newline over the '\' before it (effectively eats the '\') */ |
355 | memmove(&ptr[idx], &ptr[idx+1], strlen(&ptr[idx+1])); | 354 | memmove(&ptr[idx], &ptr[idx+1], strlen(&ptr[idx+1])); |
356 | ptr[strlen(ptr)-1] = 0; | 355 | ptr[strlen(ptr)-1] = 0; |
356 | slashes_eaten++; | ||
357 | /* substitue \r for \n if needed */ | 357 | /* substitue \r for \n if needed */ |
358 | if (ptr[idx] == '\r') | 358 | if (ptr[idx] == '\r') |
359 | ptr[idx] = '\n'; | 359 | ptr[idx] = '\n'; |
360 | } | 360 | } |
361 | 361 | ||
362 | out: | ||
363 | ptr[idx] = '\n'; | ||
364 | ptr[idx+1] = 0; | ||
365 | |||
366 | /* this accounts for discrepancies between the modified string and the | ||
367 | * original string passed in to this function */ | ||
368 | idx += slashes_eaten; | ||
369 | |||
370 | /* this accounts for the fact that A) we started at index 3, not at index | ||
371 | * 0 and B) that we added an extra '\n' at the end (if you think the next | ||
372 | * line should read 'idx += 4' remember, arrays are zero-based) */ | ||
373 | |||
374 | idx += 3; | ||
375 | |||
362 | return idx; | 376 | return idx; |
363 | } | 377 | } |
364 | 378 | ||
@@ -398,9 +412,13 @@ static char *parse_cmd_str(struct sed_cmd *sed_cmd, const char *cmdstr) | |||
398 | fatalError("only a beginning address can be specified for edit commands\n"); | 412 | fatalError("only a beginning address can be specified for edit commands\n"); |
399 | idx += parse_edit_cmd(sed_cmd, &cmdstr[idx]); | 413 | idx += parse_edit_cmd(sed_cmd, &cmdstr[idx]); |
400 | } | 414 | } |
415 | /* if it was a single-letter command (such as 'p' or 'd') we need to | ||
416 | * increment the index past that command */ | ||
417 | else | ||
418 | idx++; | ||
401 | 419 | ||
402 | /* give back whatever's left over */ | 420 | /* give back whatever's left over */ |
403 | return (char *)&cmdstr[++idx]; | 421 | return (char *)&cmdstr[idx]; |
404 | } | 422 | } |
405 | 423 | ||
406 | static void add_cmd_str(const char *cmdstr) | 424 | static void add_cmd_str(const char *cmdstr) |
@@ -412,7 +430,7 @@ static void add_cmd_str(const char *cmdstr) | |||
412 | /* trim leading whitespace and semicolons */ | 430 | /* trim leading whitespace and semicolons */ |
413 | memmove(mystr, &mystr[strspn(mystr, "; \n\r\t\v")], strlen(mystr)); | 431 | memmove(mystr, &mystr[strspn(mystr, "; \n\r\t\v")], strlen(mystr)); |
414 | /* if we ate the whole thing, that means there was just trailing | 432 | /* if we ate the whole thing, that means there was just trailing |
415 | * whitespace or a final semicolon. either way, get out */ | 433 | * whitespace or a final / no-op semicolon. either way, get out */ |
416 | if (strlen(mystr) == 0) | 434 | if (strlen(mystr) == 0) |
417 | return; | 435 | return; |
418 | /* if this is a comment, jump past it and keep going */ | 436 | /* if this is a comment, jump past it and keep going */ |
@@ -427,7 +445,7 @@ static void add_cmd_str(const char *cmdstr) | |||
427 | /* load command string into new array element, get remainder */ | 445 | /* load command string into new array element, get remainder */ |
428 | mystr = parse_cmd_str(&sed_cmds[ncmds-1], mystr); | 446 | mystr = parse_cmd_str(&sed_cmds[ncmds-1], mystr); |
429 | 447 | ||
430 | } while (mystr); | 448 | } while (mystr && strlen(mystr)); |
431 | } | 449 | } |
432 | 450 | ||
433 | 451 | ||
@@ -447,7 +465,12 @@ static void load_cmd_file(char *filename) | |||
447 | (nextline = get_line_from_file(cmdfile)) != NULL) { | 465 | (nextline = get_line_from_file(cmdfile)) != NULL) { |
448 | line = realloc(line, strlen(line) + strlen(nextline) + 1); | 466 | line = realloc(line, strlen(line) + strlen(nextline) + 1); |
449 | strcat(line, nextline); | 467 | strcat(line, nextline); |
468 | free(nextline); | ||
450 | } | 469 | } |
470 | /* eat trailing newline (if any) --if I don't do this, edit commands | ||
471 | * (aic) will print an extra newline */ | ||
472 | if (line[strlen(line)-1] == '\n') | ||
473 | line[strlen(line)-1] = 0; | ||
451 | add_cmd_str(line); | 474 | add_cmd_str(line); |
452 | free(line); | 475 | free(line); |
453 | } | 476 | } |
@@ -307,6 +307,7 @@ out: | |||
307 | static int parse_edit_cmd(struct sed_cmd *sed_cmd, const char *editstr) | 307 | static int parse_edit_cmd(struct sed_cmd *sed_cmd, const char *editstr) |
308 | { | 308 | { |
309 | int idx = 0; | 309 | int idx = 0; |
310 | int slashes_eaten = 0; | ||
310 | char *ptr; /* shorthand */ | 311 | char *ptr; /* shorthand */ |
311 | 312 | ||
312 | /* | 313 | /* |
@@ -346,19 +347,32 @@ static int parse_edit_cmd(struct sed_cmd *sed_cmd, const char *editstr) | |||
346 | while (ptr[idx] != '\\' && (ptr[idx+1] != '\n' || ptr[idx+1] != '\r')) { | 347 | while (ptr[idx] != '\\' && (ptr[idx+1] != '\n' || ptr[idx+1] != '\r')) { |
347 | idx++; | 348 | idx++; |
348 | if (!ptr[idx]) { | 349 | if (!ptr[idx]) { |
349 | ptr[idx] = '\n'; | 350 | goto out; |
350 | ptr[idx+1] = 0; | ||
351 | return idx; | ||
352 | } | 351 | } |
353 | } | 352 | } |
354 | /* move the newline over the '\' before it (effectively eats the '\') */ | 353 | /* move the newline over the '\' before it (effectively eats the '\') */ |
355 | memmove(&ptr[idx], &ptr[idx+1], strlen(&ptr[idx+1])); | 354 | memmove(&ptr[idx], &ptr[idx+1], strlen(&ptr[idx+1])); |
356 | ptr[strlen(ptr)-1] = 0; | 355 | ptr[strlen(ptr)-1] = 0; |
356 | slashes_eaten++; | ||
357 | /* substitue \r for \n if needed */ | 357 | /* substitue \r for \n if needed */ |
358 | if (ptr[idx] == '\r') | 358 | if (ptr[idx] == '\r') |
359 | ptr[idx] = '\n'; | 359 | ptr[idx] = '\n'; |
360 | } | 360 | } |
361 | 361 | ||
362 | out: | ||
363 | ptr[idx] = '\n'; | ||
364 | ptr[idx+1] = 0; | ||
365 | |||
366 | /* this accounts for discrepancies between the modified string and the | ||
367 | * original string passed in to this function */ | ||
368 | idx += slashes_eaten; | ||
369 | |||
370 | /* this accounts for the fact that A) we started at index 3, not at index | ||
371 | * 0 and B) that we added an extra '\n' at the end (if you think the next | ||
372 | * line should read 'idx += 4' remember, arrays are zero-based) */ | ||
373 | |||
374 | idx += 3; | ||
375 | |||
362 | return idx; | 376 | return idx; |
363 | } | 377 | } |
364 | 378 | ||
@@ -398,9 +412,13 @@ static char *parse_cmd_str(struct sed_cmd *sed_cmd, const char *cmdstr) | |||
398 | fatalError("only a beginning address can be specified for edit commands\n"); | 412 | fatalError("only a beginning address can be specified for edit commands\n"); |
399 | idx += parse_edit_cmd(sed_cmd, &cmdstr[idx]); | 413 | idx += parse_edit_cmd(sed_cmd, &cmdstr[idx]); |
400 | } | 414 | } |
415 | /* if it was a single-letter command (such as 'p' or 'd') we need to | ||
416 | * increment the index past that command */ | ||
417 | else | ||
418 | idx++; | ||
401 | 419 | ||
402 | /* give back whatever's left over */ | 420 | /* give back whatever's left over */ |
403 | return (char *)&cmdstr[++idx]; | 421 | return (char *)&cmdstr[idx]; |
404 | } | 422 | } |
405 | 423 | ||
406 | static void add_cmd_str(const char *cmdstr) | 424 | static void add_cmd_str(const char *cmdstr) |
@@ -412,7 +430,7 @@ static void add_cmd_str(const char *cmdstr) | |||
412 | /* trim leading whitespace and semicolons */ | 430 | /* trim leading whitespace and semicolons */ |
413 | memmove(mystr, &mystr[strspn(mystr, "; \n\r\t\v")], strlen(mystr)); | 431 | memmove(mystr, &mystr[strspn(mystr, "; \n\r\t\v")], strlen(mystr)); |
414 | /* if we ate the whole thing, that means there was just trailing | 432 | /* if we ate the whole thing, that means there was just trailing |
415 | * whitespace or a final semicolon. either way, get out */ | 433 | * whitespace or a final / no-op semicolon. either way, get out */ |
416 | if (strlen(mystr) == 0) | 434 | if (strlen(mystr) == 0) |
417 | return; | 435 | return; |
418 | /* if this is a comment, jump past it and keep going */ | 436 | /* if this is a comment, jump past it and keep going */ |
@@ -427,7 +445,7 @@ static void add_cmd_str(const char *cmdstr) | |||
427 | /* load command string into new array element, get remainder */ | 445 | /* load command string into new array element, get remainder */ |
428 | mystr = parse_cmd_str(&sed_cmds[ncmds-1], mystr); | 446 | mystr = parse_cmd_str(&sed_cmds[ncmds-1], mystr); |
429 | 447 | ||
430 | } while (mystr); | 448 | } while (mystr && strlen(mystr)); |
431 | } | 449 | } |
432 | 450 | ||
433 | 451 | ||
@@ -447,7 +465,12 @@ static void load_cmd_file(char *filename) | |||
447 | (nextline = get_line_from_file(cmdfile)) != NULL) { | 465 | (nextline = get_line_from_file(cmdfile)) != NULL) { |
448 | line = realloc(line, strlen(line) + strlen(nextline) + 1); | 466 | line = realloc(line, strlen(line) + strlen(nextline) + 1); |
449 | strcat(line, nextline); | 467 | strcat(line, nextline); |
468 | free(nextline); | ||
450 | } | 469 | } |
470 | /* eat trailing newline (if any) --if I don't do this, edit commands | ||
471 | * (aic) will print an extra newline */ | ||
472 | if (line[strlen(line)-1] == '\n') | ||
473 | line[strlen(line)-1] = 0; | ||
451 | add_cmd_str(line); | 474 | add_cmd_str(line); |
452 | free(line); | 475 | free(line); |
453 | } | 476 | } |