neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

commit 772ae3e6566a0c9207cfc60e5f02af9cd32685da
parent 840b7576e9066c46d52486fbc64b85dd7b7fdfc7
Author: zeertzjq <zeertzjq@outlook.com>
Date:   Sun, 29 May 2022 07:00:18 +0800

vim-patch:8.2.5037: cursor position may be invalid after "0;" range (#18782)

Problem:    Cursor position may be invalid after "0;" range.
Solution:   Check the cursor position when it was set by ";" in the range.
https://github.com/vim/vim/commit/4d97a565ae8be0d4debba04ebd2ac3e75a0c8010
Diffstat:
Msrc/nvim/ex_docmd.c | 25++++++++++++++++++-------
Msrc/nvim/testdir/test_excmd.vim | 8++++++++
2 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c @@ -2751,6 +2751,8 @@ int parse_cmd_address(exarg_T *eap, char **errormsg, bool silent) { int address_count = 1; linenr_T lnum; + bool need_check_cursor = false; + int ret = FAIL; // Repeat for all ',' or ';' separated addresses. for (;;) { @@ -2760,7 +2762,7 @@ int parse_cmd_address(exarg_T *eap, char **errormsg, bool silent) lnum = get_address(eap, &eap->cmd, eap->addr_type, eap->skip, silent, eap->addr_count == 0, address_count++); if (eap->cmd == NULL) { // error detected - return FAIL; + goto theend; } if (lnum == MAXLNUM) { if (*eap->cmd == '%') { // '%' - all lines @@ -2799,14 +2801,14 @@ int parse_cmd_address(exarg_T *eap, char **errormsg, bool silent) // there is no Vim command which uses '%' and // ADDR_WINDOWS or ADDR_TABS *errormsg = _(e_invrange); - return FAIL; + goto theend; } break; case ADDR_TABS_RELATIVE: case ADDR_UNSIGNED: case ADDR_QUICKFIX: *errormsg = _(e_invrange); - return FAIL; + goto theend; case ADDR_ARGUMENTS: if (ARGCOUNT == 0) { eap->line1 = eap->line2 = 0; @@ -2831,19 +2833,19 @@ int parse_cmd_address(exarg_T *eap, char **errormsg, bool silent) // '*' - visual area if (eap->addr_type != ADDR_LINES) { *errormsg = _(e_invrange); - return FAIL; + goto theend; } eap->cmd++; if (!eap->skip) { pos_T *fp = getmark('<', false); if (check_mark(fp) == FAIL) { - return FAIL; + goto theend; } eap->line1 = fp->lnum; fp = getmark('>', false); if (check_mark(fp) == FAIL) { - return FAIL; + goto theend; } eap->line2 = fp->lnum; eap->addr_count++; @@ -2857,11 +2859,14 @@ int parse_cmd_address(exarg_T *eap, char **errormsg, bool silent) if (*eap->cmd == ';') { if (!eap->skip) { curwin->w_cursor.lnum = eap->line2; + // Don't leave the cursor on an illegal line or column, but do // accept zero as address, so 0;/PATTERN/ works correctly. + // Check the cursor position before returning. if (eap->line2 > 0) { check_cursor(); } + need_check_cursor = true; } } else if (*eap->cmd != ',') { break; @@ -2877,7 +2882,13 @@ int parse_cmd_address(exarg_T *eap, char **errormsg, bool silent) eap->addr_count = 0; } } - return OK; + ret = OK; + +theend: + if (need_check_cursor) { + check_cursor(); + } + return ret; } /// Check for an Ex command with optional tail. diff --git a/src/nvim/testdir/test_excmd.vim b/src/nvim/testdir/test_excmd.vim @@ -422,5 +422,13 @@ func Test_address_line_overflow() bwipe! endfunc +" This was leaving the cursor in line zero +func Test_using_zero_in_range() + new + norm o00 + silent! 0;s/\%') + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab