summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2026-04-22 09:49:06 +0800
committergithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>2026-04-22 02:35:11 +0000
commit15d824e5d65d6347808f700badfe3d70b721baf7 (patch)
tree7fe030454cdd041aae52d5324d3ce99e25783541
parente767b4843b234a07d314286783b904fc7843e1d4 (diff)
vim-patch:9.2.0385: Integer overflow with "ze" and large 'sidescrolloff' (#39289)
Problem: Integer overflow with "ze" and large 'sidescrolloff'. Solution: Check for overflow to avoid negative w_leftcol (zeertzjq). closes: vim/vim#20026 https://github.com/vim/vim/commit/33f3965087b01dccf4382ed419d34799ffd66cd9 (cherry picked from commit 1569a71c8a51287628cb5257e45d2e68f1181551)
-rw-r--r--src/nvim/move.c5
-rw-r--r--src/nvim/normal.c5
-rw-r--r--test/old/testdir/test_normal.vim25
3 files changed, 30 insertions, 5 deletions
diff --git a/src/nvim/move.c b/src/nvim/move.c
index 0af3e3e28c..bcb37dbda6 100644
--- a/src/nvim/move.c
+++ b/src/nvim/move.c
@@ -885,9 +885,8 @@ void curs_columns(win_T *wp, int may_scroll)
// If scrolling is off, wp->w_leftcol is assumed to be 0
// If Cursor is left of the screen, scroll rightwards.
- // If Cursor is right of the screen, scroll leftwards
- // If we get closer to the edge than 'sidescrolloff', scroll a little
- // extra
+ // If Cursor is right of the screen, scroll leftwards.
+ // If we get closer to the edge than 'sidescrolloff', scroll a little extra.
int64_t siso = get_sidescrolloff_value(wp);
int64_t off_left = startcol - wp->w_leftcol - siso;
int64_t off_right = endcol - wp->w_leftcol - (wp->w_view_width - siso) + 1;
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index b3d3b83ac1..ddb0966b7d 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -2911,9 +2911,10 @@ static void nv_zet(cmdarg_T *cap)
int n = curwin->w_view_width - win_col_off(curwin);
if (col + siso < n) {
col = 0;
- } else {
- // TODO(zeertzjq): check for overflow
+ } else if (siso - n < INT_MAX - col) {
col = (int)(col + siso - n + 1);
+ } else {
+ col = INT_MAX;
}
if (curwin->w_leftcol != col) {
curwin->w_leftcol = col;
diff --git a/test/old/testdir/test_normal.vim b/test/old/testdir/test_normal.vim
index 92b1b789c1..6a272c80f4 100644
--- a/test/old/testdir/test_normal.vim
+++ b/test/old/testdir/test_normal.vim
@@ -1202,6 +1202,31 @@ func Test_normal17_z_scroll_hor2()
bw!
endfunc
+func Test_large_sidescrolloff_no_overflow()
+ 10new
+ 20vsp
+ setlocal nowrap sidescrolloff=2147483647
+ call setline(1, repeat('a', 40))
+
+ normal! $
+ redraw!
+ call assert_equal(29, winsaveview().leftcol)
+
+ normal! zs
+ redraw!
+ call assert_equal(29, winsaveview().leftcol)
+
+ normal! ze
+ redraw!
+ call assert_equal(29, winsaveview().leftcol)
+
+ normal! 0
+ redraw!
+ call assert_equal(0, winsaveview().leftcol)
+
+ bw!
+endfunc
+
" Test for commands that scroll the window horizontally. Test with folds.
" H, M, L, CTRL-E, CTRL-Y, CTRL-U, CTRL-D, PageUp, PageDown commands
func Test_vert_scroll_cmds()