diff -up vim82/src/ex_docmd.c.cve1927 vim82/src/ex_docmd.c --- vim82/src/ex_docmd.c.cve1927 2021-03-22 10:02:42.000000000 +0100 +++ vim82/src/ex_docmd.c 2022-06-13 15:29:45.099472751 +0200 @@ -3081,6 +3081,8 @@ parse_cmd_address(exarg_T *eap, char **e { int address_count = 1; linenr_T lnum; + int need_check_cursor = FALSE; + int ret = FAIL; // Repeat for all ',' or ';' separated addresses. for (;;) @@ -3091,7 +3093,7 @@ parse_cmd_address(exarg_T *eap, char **e 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 @@ -3136,14 +3138,14 @@ parse_cmd_address(exarg_T *eap, char **e // 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; @@ -3175,7 +3177,7 @@ parse_cmd_address(exarg_T *eap, char **e if (eap->addr_type != ADDR_LINES) { *errormsg = _(e_invrange); - return FAIL; + goto theend; } ++eap->cmd; @@ -3183,11 +3185,11 @@ parse_cmd_address(exarg_T *eap, char **e { 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; } @@ -3202,10 +3204,13 @@ parse_cmd_address(exarg_T *eap, char **e 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 != ',') @@ -3221,7 +3226,12 @@ parse_cmd_address(exarg_T *eap, char **e if (lnum == MAXLNUM) eap->addr_count = 0; } - return OK; + ret = OK; + +theend: + if (need_check_cursor) + check_cursor(); + return ret; } /* diff -up vim82/src/testdir/test_excmd.vim.cve1927 vim82/src/testdir/test_excmd.vim --- vim82/src/testdir/test_excmd.vim.cve1927 2022-06-13 15:26:53.941517542 +0200 +++ vim82/src/testdir/test_excmd.vim 2022-06-13 15:30:53.972860361 +0200 @@ -536,4 +536,13 @@ func Test_sandbox() sandbox call Sandbox_tests() 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