diff options
author | zeertzjq <zeertzjq@outlook.com> | 2024-05-11 17:46:22 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-11 17:46:22 +0800 |
commit | 14693353d566d126d1e8f28a8e6cbc10e27c09d1 (patch) | |
tree | be4db24fbd50dc44d5a0f57a3b9c08b9c12038e3 | |
parent | 854c362cc88786b45e7c94a124c718dac0a03660 (diff) | |
download | rneovim-14693353d566d126d1e8f28a8e6cbc10e27c09d1.tar.gz rneovim-14693353d566d126d1e8f28a8e6cbc10e27c09d1.tar.bz2 rneovim-14693353d566d126d1e8f28a8e6cbc10e27c09d1.zip |
vim-patch:9.1.0406: Divide by zero with getmousepos() and 'smoothscroll' (#28701)
Problem: Divide by zero with getmousepos() and 'smoothscroll'.
Solution: Don't compute skip_lines when width1 is zero.
(zeertzjq)
closes: vim/vim#14747
https://github.com/vim/vim/commit/031a745608d615d56f9d79bb0f76e2a74b2eaf14
-rw-r--r-- | src/nvim/mouse.c | 21 | ||||
-rw-r--r-- | src/nvim/move.c | 6 | ||||
-rw-r--r-- | test/old/testdir/test_functions.vim | 67 |
3 files changed, 84 insertions, 10 deletions
diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 9d30d7d5ab..f393b0fd0f 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -1621,16 +1621,21 @@ bool mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump) } if (win->w_skipcol > 0 && lnum == win->w_topline) { - // Adjust for 'smoothscroll' clipping the top screen lines. - // A similar formula is used in curs_columns(). int width1 = win->w_width_inner - win_col_off(win); - int skip_lines = 0; - if (win->w_skipcol > width1) { - skip_lines = (win->w_skipcol - width1) / (width1 + win_col_off2(win)) + 1; - } else if (win->w_skipcol > 0) { - skip_lines = 1; + + if (width1 > 0) { + int skip_lines = 0; + + // Adjust for 'smoothscroll' clipping the top screen lines. + // A similar formula is used in curs_columns(). + if (win->w_skipcol > width1) { + skip_lines = (win->w_skipcol - width1) / (width1 + win_col_off2(win)) + 1; + } else if (win->w_skipcol > 0) { + skip_lines = 1; + } + + count -= skip_lines; } - count -= skip_lines; } if (count > row) { diff --git a/src/nvim/move.c b/src/nvim/move.c index 078ce3d72c..66667cecc4 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -1974,11 +1974,13 @@ void scroll_cursor_bot(win_T *wp, int min_scroll, bool set_topbot) // need to scroll the additional clipped lines to scroll past the // top line before we can move on to the other lines. int top_plines = plines_win_nofill(wp, wp->w_topline, false); - int skip_lines = 0; int width1 = wp->w_width_inner - win_col_off(wp); + if (width1 > 0) { int width2 = width1 + win_col_off2(wp); - // similar formula is used in curs_columns() + int skip_lines = 0; + + // A similar formula is used in curs_columns(). if (wp->w_skipcol > width1) { skip_lines += (wp->w_skipcol - width1) / width2 + 1; } else if (wp->w_skipcol > 0) { diff --git a/test/old/testdir/test_functions.vim b/test/old/testdir/test_functions.vim index ea0e3790cc..7c712818f9 100644 --- a/test/old/testdir/test_functions.vim +++ b/test/old/testdir/test_functions.vim @@ -3399,6 +3399,73 @@ func Test_getmousepos() \ column: 8, \ coladd: 21, \ }, getmousepos()) + + 30vnew + setlocal smoothscroll number + call setline(1, join(range(100))) + exe "normal! \<C-E>" + call Ntest_setmouse(1, 5) + call assert_equal(#{ + \ screenrow: 1, + \ screencol: 5, + \ winid: win_getid(), + \ winrow: 1, + \ wincol: 5, + \ line: 1, + \ column: 27, + \ coladd: 0, + \ }, getmousepos()) + call Ntest_setmouse(2, 5) + call assert_equal(#{ + \ screenrow: 2, + \ screencol: 5, + \ winid: win_getid(), + \ winrow: 2, + \ wincol: 5, + \ line: 1, + \ column: 53, + \ coladd: 0, + \ }, getmousepos()) + + exe "normal! \<C-E>" + call Ntest_setmouse(1, 5) + call assert_equal(#{ + \ screenrow: 1, + \ screencol: 5, + \ winid: win_getid(), + \ winrow: 1, + \ wincol: 5, + \ line: 1, + \ column: 53, + \ coladd: 0, + \ }, getmousepos()) + call Ntest_setmouse(2, 5) + call assert_equal(#{ + \ screenrow: 2, + \ screencol: 5, + \ winid: win_getid(), + \ winrow: 2, + \ wincol: 5, + \ line: 1, + \ column: 79, + \ coladd: 0, + \ }, getmousepos()) + + vert resize 4 + call Ntest_setmouse(2, 2) + " This used to crash Vim + call assert_equal(#{ + \ screenrow: 2, + \ screencol: 2, + \ winid: win_getid(), + \ winrow: 2, + \ wincol: 2, + \ line: 1, + \ column: 53, + \ coladd: 0, + \ }, getmousepos()) + + bwipe! bwipe! endfunc |