Mercurial > vim
changeset 35159:531c6b18dd0f v9.1.0406
patch 9.1.0406: Divide by zero with getmousepos() and 'smoothscroll'
Commit: https://github.com/vim/vim/commit/031a745608d615d56f9d79bb0f76e2a74b2eaf14
Author: zeertzjq <zeertzjq@outlook.com>
Date: Sat May 11 11:23:37 2024 +0200
patch 9.1.0406: Divide by zero with getmousepos() and 'smoothscroll'
Problem: Divide by zero with getmousepos() and 'smoothscroll'.
Solution: Don't compute skip_lines when width1 is zero.
(zeertzjq)
closes: #14747
Signed-off-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sat, 11 May 2024 11:30:13 +0200 |
parents | 7191ebc28df2 |
children | ee6031d181da |
files | src/mouse.c src/move.c src/testdir/test_functions.vim src/version.c |
diffstat | 4 files changed, 87 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/src/mouse.c +++ b/src/mouse.c @@ -3029,16 +3029,22 @@ mouse_comp_pos( 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 - win_col_off(win); - int skip_lines = 0; - if (win->w_skipcol > width1) - skip_lines = (win->w_skipcol - width1) + + 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; + else if (win->w_skipcol > 0) + skip_lines = 1; + + count -= skip_lines; + } } if (count > row)
--- a/src/move.c +++ b/src/move.c @@ -2617,12 +2617,14 @@ scroll_cursor_bot(int min_scroll, int se plines_win #endif (curwin, curwin->w_topline, FALSE); - int skip_lines = 0; int width1 = curwin->w_width - curwin_col_off(); + if (width1 > 0) { int width2 = width1 + curwin_col_off2(); - // similar formula is used in curs_columns() + int skip_lines = 0; + + // A similar formula is used in curs_columns(). if (curwin->w_skipcol > width1) skip_lines += (curwin->w_skipcol - width1) / width2 + 1; else if (curwin->w_skipcol > 0)
--- a/src/testdir/test_functions.vim +++ b/src/testdir/test_functions.vim @@ -3697,6 +3697,73 @@ func Test_getmousepos() \ column: 8, \ coladd: 21, \ }, getmousepos()) + + 30vnew + setlocal smoothscroll number + call setline(1, join(range(100))) + exe "normal! \<C-E>" + call test_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 test_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 test_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 test_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 test_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