aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2021-04-15 12:05:45 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2021-04-15 13:09:12 +0200
commitd488def0e453781e0471cfb0971ad709a95c7919 (patch)
treefc9879043b14c193f4ba4f0b8c63d5c77b45818b
parent5d1bb58b13d4a805538e231584721e5738932efc (diff)
downloadbusybox-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.c22
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