diff options
author | Ron Yorston <rmy@pobox.com> | 2021-06-16 14:46:01 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-06-16 23:53:03 +0200 |
commit | ac04eb3657f99f6952971d8ceb8a82d73b783de8 (patch) | |
tree | ba7cf6b16960129600aafe9288657e75bb9f96b8 | |
parent | f1d21b743485defb39fada03b27878efb1e2f7e3 (diff) | |
download | busybox-w32-ac04eb3657f99f6952971d8ceb8a82d73b783de8.tar.gz busybox-w32-ac04eb3657f99f6952971d8ceb8a82d73b783de8.tar.bz2 busybox-w32-ac04eb3657f99f6952971d8ceb8a82d73b783de8.zip |
vi: up/down motion beyond end of file should fail
In traditional vi and vim line motion commands ('+'/'-'/'j'/'k')
fail if the movement would exceed the bounds of the file. BusyBox vi
allowed such commands to succeed, leaving the cursor on the first or
last character of the file.
Make BusyBox vi work like vi/vim.
For the 'G'/'H'/'L' commands traditional vi treats an out of bounds
result as an error, vim doesn't. BusyBox vi behaves like vim, both
before and after this patch.
function old new delta
do_cmd 4785 4851 +66
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 66/0) Total: 66 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | editors/vi.c | 63 |
1 files changed, 38 insertions, 25 deletions
diff --git a/editors/vi.c b/editors/vi.c index 3daa0756b..231c62809 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
@@ -3635,24 +3635,30 @@ static void do_cmd(int c) | |||
3635 | case 10: // Newline ^J | 3635 | case 10: // Newline ^J |
3636 | case 'j': // j- goto next line, same col | 3636 | case 'j': // j- goto next line, same col |
3637 | case KEYCODE_DOWN: // cursor key Down | 3637 | case KEYCODE_DOWN: // cursor key Down |
3638 | case 13: // Carriage Return ^M | ||
3639 | case '+': // +- goto next line | ||
3640 | q = dot; | ||
3638 | do { | 3641 | do { |
3639 | dot_next(); // go to next B-o-l | 3642 | p = next_line(q); |
3643 | if (p == end_line(q)) { | ||
3644 | indicate_error(); | ||
3645 | goto dc1; | ||
3646 | } | ||
3647 | q = p; | ||
3640 | } while (--cmdcnt > 0); | 3648 | } while (--cmdcnt > 0); |
3641 | // try to stay in saved column | 3649 | dot = q; |
3642 | dot = cindex == C_END ? end_line(dot) : move_to_col(dot, cindex); | 3650 | if (c == 13 || c == '+') { |
3643 | keep_index = TRUE; | 3651 | dot_skip_over_ws(); |
3652 | } else { | ||
3653 | // try to stay in saved column | ||
3654 | dot = cindex == C_END ? end_line(dot) : move_to_col(dot, cindex); | ||
3655 | keep_index = TRUE; | ||
3656 | } | ||
3644 | break; | 3657 | break; |
3645 | case 12: // ctrl-L force redraw whole screen | 3658 | case 12: // ctrl-L force redraw whole screen |
3646 | case 18: // ctrl-R force redraw | 3659 | case 18: // ctrl-R force redraw |
3647 | redraw(TRUE); // this will redraw the entire display | 3660 | redraw(TRUE); // this will redraw the entire display |
3648 | break; | 3661 | break; |
3649 | case 13: // Carriage Return ^M | ||
3650 | case '+': // +- goto next line | ||
3651 | do { | ||
3652 | dot_next(); | ||
3653 | } while (--cmdcnt > 0); | ||
3654 | dot_skip_over_ws(); | ||
3655 | break; | ||
3656 | case 21: // ctrl-U scroll up half screen | 3662 | case 21: // ctrl-U scroll up half screen |
3657 | dot_scroll((rows - 2) / 2, -1); | 3663 | dot_scroll((rows - 2) / 2, -1); |
3658 | break; | 3664 | break; |
@@ -3818,12 +3824,6 @@ static void do_cmd(int c) | |||
3818 | case ',': // ,- repeat latest search in opposite direction | 3824 | case ',': // ,- repeat latest search in opposite direction |
3819 | dot_to_char(c != ',' ? last_search_cmd : last_search_cmd ^ 0x20); | 3825 | dot_to_char(c != ',' ? last_search_cmd : last_search_cmd ^ 0x20); |
3820 | break; | 3826 | break; |
3821 | case '-': // -- goto prev line | ||
3822 | do { | ||
3823 | dot_prev(); | ||
3824 | } while (--cmdcnt > 0); | ||
3825 | dot_skip_over_ws(); | ||
3826 | break; | ||
3827 | #if ENABLE_FEATURE_VI_DOT_CMD | 3827 | #if ENABLE_FEATURE_VI_DOT_CMD |
3828 | case '.': // .- repeat the last modifying command | 3828 | case '.': // .- repeat the last modifying command |
3829 | // Stuff the last_modifying_cmd back into stdin | 3829 | // Stuff the last_modifying_cmd back into stdin |
@@ -4029,9 +4029,10 @@ static void do_cmd(int c) | |||
4029 | if (cmdcnt > (rows - 1)) { | 4029 | if (cmdcnt > (rows - 1)) { |
4030 | cmdcnt = (rows - 1); | 4030 | cmdcnt = (rows - 1); |
4031 | } | 4031 | } |
4032 | if (--cmdcnt > 0) { | 4032 | while (--cmdcnt > 0) { |
4033 | do_cmd('+'); | 4033 | dot_next(); |
4034 | } | 4034 | } |
4035 | dot_begin(); | ||
4035 | dot_skip_over_ws(); | 4036 | dot_skip_over_ws(); |
4036 | break; | 4037 | break; |
4037 | case 'I': // I- insert before first non-blank | 4038 | case 'I': // I- insert before first non-blank |
@@ -4068,8 +4069,8 @@ static void do_cmd(int c) | |||
4068 | if (cmdcnt > (rows - 1)) { | 4069 | if (cmdcnt > (rows - 1)) { |
4069 | cmdcnt = (rows - 1); | 4070 | cmdcnt = (rows - 1); |
4070 | } | 4071 | } |
4071 | if (--cmdcnt > 0) { | 4072 | while (--cmdcnt > 0) { |
4072 | do_cmd('-'); | 4073 | dot_prev(); |
4073 | } | 4074 | } |
4074 | dot_begin(); | 4075 | dot_begin(); |
4075 | dot_skip_over_ws(); | 4076 | dot_skip_over_ws(); |
@@ -4234,12 +4235,24 @@ static void do_cmd(int c) | |||
4234 | } | 4235 | } |
4235 | case 'k': // k- goto prev line, same col | 4236 | case 'k': // k- goto prev line, same col |
4236 | case KEYCODE_UP: // cursor key Up | 4237 | case KEYCODE_UP: // cursor key Up |
4238 | case '-': // -- goto prev line | ||
4239 | q = dot; | ||
4237 | do { | 4240 | do { |
4238 | dot_prev(); | 4241 | p = prev_line(q); |
4242 | if (p == begin_line(q)) { | ||
4243 | indicate_error(); | ||
4244 | goto dc1; | ||
4245 | } | ||
4246 | q = p; | ||
4239 | } while (--cmdcnt > 0); | 4247 | } while (--cmdcnt > 0); |
4240 | // try to stay in saved column | 4248 | dot = q; |
4241 | dot = cindex == C_END ? end_line(dot) : move_to_col(dot, cindex); | 4249 | if (c == '-') { |
4242 | keep_index = TRUE; | 4250 | dot_skip_over_ws(); |
4251 | } else { | ||
4252 | // try to stay in saved column | ||
4253 | dot = cindex == C_END ? end_line(dot) : move_to_col(dot, cindex); | ||
4254 | keep_index = TRUE; | ||
4255 | } | ||
4243 | break; | 4256 | break; |
4244 | case 'r': // r- replace the current char with user input | 4257 | case 'r': // r- replace the current char with user input |
4245 | c1 = get_one_char(); // get the replacement char | 4258 | c1 = get_one_char(); // get the replacement char |