diff options
author | zeertzjq <zeertzjq@outlook.com> | 2022-09-17 10:20:06 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-17 10:20:06 +0800 |
commit | 72e1041429565c3a592dedc36e8b3004a24cdcc4 (patch) | |
tree | b4db84978b45e24710361242d5276bf7c9374c77 | |
parent | 26b54d5c169d7d4afeb5433355b29eee78c12add (diff) | |
download | rneovim-72e1041429565c3a592dedc36e8b3004a24cdcc4.tar.gz rneovim-72e1041429565c3a592dedc36e8b3004a24cdcc4.tar.bz2 rneovim-72e1041429565c3a592dedc36e8b3004a24cdcc4.zip |
vim-patch:9.0.0483: illegal memory access when replacing in virtualedit mode (#20225)
Problem: Illegal memory access when replacing in virtualedit mode.
Solution: Check for replacing NUL after Tab.
https://github.com/vim/vim/commit/c249913edc35c0e666d783bfc21595cf9f7d9e0d
Cherry-pick Test_virtualedit_mouse() from patch 9.0.0177.
-rw-r--r-- | src/nvim/ops.c | 12 | ||||
-rw-r--r-- | src/nvim/testdir/test_virtualedit.vim | 49 |
2 files changed, 59 insertions, 2 deletions
diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 83484859ed..6391644f83 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -1961,6 +1961,8 @@ static int op_replace(oparg_T *oap, int c) // TODO(bfredl): we could batch all the splicing // done on the same line, at least while (ltoreq(curwin->w_cursor, oap->end)) { + bool done = false; + n = gchar_cursor(); if (n != NUL) { int new_byte_len = utf_char2len(c); @@ -1973,6 +1975,7 @@ static int op_replace(oparg_T *oap, int c) oap->end.col += new_byte_len - old_byte_len; } replace_character(c); + done = true; } else { if (n == TAB) { int end_vcol = 0; @@ -1988,9 +1991,14 @@ static int op_replace(oparg_T *oap, int c) getvpos(&oap->end, end_vcol); } } - pbyte(curwin->w_cursor, c); + // with "coladd" set may move to just after a TAB + if (gchar_cursor() != NUL) { + pbyte(curwin->w_cursor, c); + done = true; + } } - } else if (virtual_op && curwin->w_cursor.lnum == oap->end.lnum) { + } + if (!done && virtual_op && curwin->w_cursor.lnum == oap->end.lnum) { int virtcols = oap->end.coladd; if (curwin->w_cursor.lnum == oap->start.lnum diff --git a/src/nvim/testdir/test_virtualedit.vim b/src/nvim/testdir/test_virtualedit.vim index 522ca17675..e712896562 100644 --- a/src/nvim/testdir/test_virtualedit.vim +++ b/src/nvim/testdir/test_virtualedit.vim @@ -481,4 +481,53 @@ func Test_global_local_virtualedit() set virtualedit& endfunc +func Test_virtualedit_mouse() + let save_mouse = &mouse + set mouse=a + set virtualedit=all + new + + call setline(1, ["text\tword"]) + redraw + call Ntest_setmouse(1, 4) + call feedkeys("\<LeftMouse>", "xt") + call assert_equal([0, 1, 4, 0, 4], getcurpos()) + call Ntest_setmouse(1, 5) + call feedkeys("\<LeftMouse>", "xt") + call assert_equal([0, 1, 5, 0, 5], getcurpos()) + call Ntest_setmouse(1, 6) + call feedkeys("\<LeftMouse>", "xt") + call assert_equal([0, 1, 5, 1, 6], getcurpos()) + call Ntest_setmouse(1, 7) + call feedkeys("\<LeftMouse>", "xt") + call assert_equal([0, 1, 5, 2, 7], getcurpos()) + call Ntest_setmouse(1, 8) + call feedkeys("\<LeftMouse>", "xt") + call assert_equal([0, 1, 5, 3, 8], getcurpos()) + call Ntest_setmouse(1, 9) + call feedkeys("\<LeftMouse>", "xt") + call assert_equal([0, 1, 6, 0, 9], getcurpos()) + call Ntest_setmouse(1, 15) + call feedkeys("\<LeftMouse>", "xt") + call assert_equal([0, 1, 10, 2, 15], getcurpos()) + + bwipe! + let &mouse = save_mouse + set virtualedit& +endfunc + +" this was replacing the NUL at the end of the line +func Test_virtualedit_replace_after_tab() + new + s/\v/ 0 + set ve=all + let @" = '' + sil! norm vPvr0 + + call assert_equal("\t0", getline(1)) + set ve& + bwipe! +endfunc + + " vim: shiftwidth=2 sts=2 expandtab |