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 | } |
