aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2022-03-10 20:32:13 +0800
committerGitHub <noreply@github.com>2022-03-10 20:32:13 +0800
commit3a32aa96159ae1fdd0efd55389a4b1c2f92c98f7 (patch)
tree4dce94dcf97eb45765253bc9834e64a9ed014077 /src
parent9e9322b222566c0f92bb6df034d9b316317c81d5 (diff)
parenta80ec88906220b6527c553f7614180ba3bfde169 (diff)
downloadrneovim-3a32aa96159ae1fdd0efd55389a4b1c2f92c98f7.tar.gz
rneovim-3a32aa96159ae1fdd0efd55389a4b1c2f92c98f7.tar.bz2
rneovim-3a32aa96159ae1fdd0efd55389a4b1c2f92c98f7.zip
Merge pull request #17671 from zeertzjq/vim-8.2.3949
vim-patch:8.2.{3949,3950}: fix two crashes with /\%V
Diffstat (limited to 'src')
-rw-r--r--src/nvim/charset.c10
-rw-r--r--src/nvim/regexp.c10
-rw-r--r--src/nvim/testdir/test_regexp_latin.vim16
3 files changed, 29 insertions, 7 deletions
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
index 97aac67627..3383dd2a76 100644
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.c
@@ -928,10 +928,12 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en
// continue until the NUL
posptr = NULL;
} else {
- // Special check for an empty line, which can happen on exit, when
- // ml_get_buf() always returns an empty string.
- if (*ptr == NUL) {
- pos->col = 0;
+ // In a few cases the position can be beyond the end of the line.
+ for (colnr_T i = 0; i < pos->col; i++) {
+ if (ptr[i] == NUL) {
+ pos->col = i;
+ break;
+ }
}
posptr = ptr + pos->col;
posptr -= utf_head_off(line, posptr);
diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c
index 412cdac21b..009a26d4e0 100644
--- a/src/nvim/regexp.c
+++ b/src/nvim/regexp.c
@@ -1136,8 +1136,8 @@ static bool reg_match_visual(void)
return false;
}
+ col = (colnr_T)(rex.input - rex.line);
if (mode == 'v') {
- col = (colnr_T)(rex.input - rex.line);
if ((lnum == top.lnum && col < top.col)
|| (lnum == bot.lnum && col >= bot.col + (*p_sel != 'e'))) {
return false;
@@ -1152,8 +1152,12 @@ static bool reg_match_visual(void)
if (top.col == MAXCOL || bot.col == MAXCOL || curswant == MAXCOL) {
end = MAXCOL;
}
- unsigned int cols_u = win_linetabsize(wp, rex.line,
- (colnr_T)(rex.input - rex.line));
+
+ // getvvcol() flushes rex.line, need to get it again
+ rex.line = reg_getline(rex.lnum);
+ rex.input = rex.line + col;
+
+ unsigned int cols_u = win_linetabsize(wp, rex.line, col);
assert(cols_u <= MAXCOL);
colnr_T cols = (colnr_T)cols_u;
if (cols < start || cols > end - (*p_sel == 'e')) {
diff --git a/src/nvim/testdir/test_regexp_latin.vim b/src/nvim/testdir/test_regexp_latin.vim
index a92f7e1192..a0f5ebfb9f 100644
--- a/src/nvim/testdir/test_regexp_latin.vim
+++ b/src/nvim/testdir/test_regexp_latin.vim
@@ -795,4 +795,20 @@ func Test_using_mark_position()
bwipe!
endfunc
+func Test_using_visual_position()
+ " this was using freed memory
+ new
+ exe "norm 0o\<Esc>\<C-V>k\<C-X>o0"
+ /\%V
+ bwipe!
+endfunc
+
+func Test_using_invalid_visual_position()
+ " this was going beyond the end of the line
+ new
+ exe "norm 0o000\<Esc>0\<C-V>$s0"
+ /\%V
+ bwipe!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab