diff options
author | Ron Yorston <rmy@pobox.com> | 2021-04-15 12:05:45 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-04-15 13:09:12 +0200 |
commit | d488def0e453781e0471cfb0971ad709a95c7919 (patch) | |
tree | fc9879043b14c193f4ba4f0b8c63d5c77b45818b | |
parent | 5d1bb58b13d4a805538e231584721e5738932efc (diff) | |
download | busybox-w32-d488def0e453781e0471cfb0971ad709a95c7919.tar.gz busybox-w32-d488def0e453781e0471cfb0971ad709a95c7919.tar.bz2 busybox-w32-d488def0e453781e0471cfb0971ad709a95c7919.zip |
vi: detect and warn about invalid line addresses
BusyBox vi didn't have proper handling for invalid markers or
unsuccessful searches in colon line addresses. This could result
in the wrong lines being affected by a change.
Detect when an invalid address is specified, propagate an error
indicator up the call chain and issue a warning.
function old new delta
colon 3604 3661 +57
.rodata 105195 105211 +16
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 73/0) Total: 73 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | editors/vi.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/editors/vi.c b/editors/vi.c index 9c32ed836..1d326f454 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
@@ -2360,14 +2360,15 @@ static char *get_one_address(char *p, int *addr) // get colon addr, if present | |||
2360 | p++; | 2360 | p++; |
2361 | c = tolower(*p); | 2361 | c = tolower(*p); |
2362 | p++; | 2362 | p++; |
2363 | q = NULL; | ||
2363 | if (c >= 'a' && c <= 'z') { | 2364 | if (c >= 'a' && c <= 'z') { |
2364 | // we have a mark | 2365 | // we have a mark |
2365 | c = c - 'a'; | 2366 | c = c - 'a'; |
2366 | q = mark[(unsigned char) c]; | 2367 | q = mark[(unsigned char) c]; |
2367 | if (q != NULL) { // is mark valid | ||
2368 | *addr = count_lines(text, q); | ||
2369 | } | ||
2370 | } | 2368 | } |
2369 | if (q == NULL) // is mark valid | ||
2370 | return NULL; | ||
2371 | *addr = count_lines(text, q); | ||
2371 | } | 2372 | } |
2372 | # endif | 2373 | # endif |
2373 | # if ENABLE_FEATURE_VI_SEARCH | 2374 | # if ENABLE_FEATURE_VI_SEARCH |
@@ -2383,9 +2384,9 @@ static char *get_one_address(char *p, int *addr) // get colon addr, if present | |||
2383 | p++; | 2384 | p++; |
2384 | q = char_search(next_line(dot), last_search_pattern + 1, | 2385 | q = char_search(next_line(dot), last_search_pattern + 1, |
2385 | (FORWARD << 1) | FULL); | 2386 | (FORWARD << 1) | FULL); |
2386 | if (q != NULL) { | 2387 | if (q == NULL) |
2387 | *addr = count_lines(text, q); | 2388 | return NULL; |
2388 | } | 2389 | *addr = count_lines(text, q); |
2389 | } | 2390 | } |
2390 | # endif | 2391 | # endif |
2391 | else if (*p == '$') { // the last line in file | 2392 | else if (*p == '$') { // the last line in file |
@@ -2422,6 +2423,8 @@ static char *get_address(char *p, int *b, int *e) // get two colon addrs, if pre | |||
2422 | state = GET_SECOND; | 2423 | state = GET_SECOND; |
2423 | } else if (state == GET_FIRST || state == GET_SECOND) { | 2424 | } else if (state == GET_FIRST || state == GET_SECOND) { |
2424 | p = get_one_address(p, state == GET_FIRST ? b : e); | 2425 | p = get_one_address(p, state == GET_FIRST ? b : e); |
2426 | if (p == NULL) | ||
2427 | break; | ||
2425 | state |= GOT; | 2428 | state |= GOT; |
2426 | } else { | 2429 | } else { |
2427 | break; | 2430 | break; |
@@ -2536,9 +2539,7 @@ static void colon(char *buf) | |||
2536 | char *fn, cmd[MAX_INPUT_LEN], args[MAX_INPUT_LEN]; | 2539 | char *fn, cmd[MAX_INPUT_LEN], args[MAX_INPUT_LEN]; |
2537 | int i, l, li, b, e; | 2540 | int i, l, li, b, e; |
2538 | int useforce; | 2541 | int useforce; |
2539 | # if ENABLE_FEATURE_VI_SEARCH || ENABLE_FEATURE_ALLOW_EXEC | ||
2540 | char *orig_buf; | 2542 | char *orig_buf; |
2541 | # endif | ||
2542 | 2543 | ||
2543 | // :3154 // if (-e line 3154) goto it else stay put | 2544 | // :3154 // if (-e line 3154) goto it else stay put |
2544 | // :4,33w! foo // write a portion of buffer to file "foo" | 2545 | // :4,33w! foo // write a portion of buffer to file "foo" |
@@ -2568,7 +2569,12 @@ static void colon(char *buf) | |||
2568 | fn = current_filename; | 2569 | fn = current_filename; |
2569 | 2570 | ||
2570 | // look for optional address(es) :. :1 :1,9 :'q,'a :% | 2571 | // look for optional address(es) :. :1 :1,9 :'q,'a :% |
2572 | orig_buf = buf; | ||
2571 | buf = get_address(buf, &b, &e); | 2573 | buf = get_address(buf, &b, &e); |
2574 | if (buf == NULL) { | ||
2575 | status_line_bold("Bad address: %s", orig_buf); | ||
2576 | goto ret; | ||
2577 | } | ||
2572 | 2578 | ||
2573 | # if ENABLE_FEATURE_VI_SEARCH || ENABLE_FEATURE_ALLOW_EXEC | 2579 | # if ENABLE_FEATURE_VI_SEARCH || ENABLE_FEATURE_ALLOW_EXEC |
2574 | // remember orig command line | 2580 | // remember orig command line |