From: Jaehwang Jung Date: Sun, 19 Apr 2026 18:32:55 +0000 (+0000) Subject: patch 9.2.0362: division by zero with smoothscroll and small windows X-Git-Tag: v9.2.0362^0 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=0e31fb024c846e36bb0d26d01ff179a0d1b3eae4;p=thirdparty%2Fvim.git patch 9.2.0362: division by zero with smoothscroll and small windows Problem: Resizing a smoothscrolled wrapped window to its textoff width with 'showbreak' can leave wrapped continuation lines with zero text width. win_lbr_chartabsize() still runs the partial max_head_vcol calculation in that state and divides by width2, crashing during redraw. Solution: Skip that partial head calculation when the wrapped continuation width is zero, matching the other width2 guards in charset.c (Jaehwang Jung) closes: #20012 AI-assisted: Codex Signed-off-by: Jaehwang Jung Signed-off-by: Christian Brabandt --- diff --git a/src/charset.c b/src/charset.c index 8ad768d354..bf7c59620f 100644 --- a/src/charset.c +++ b/src/charset.c @@ -1468,7 +1468,8 @@ win_lbr_chartabsize( if (max_head_vcol == 0 || vcol + size + added < max_head_vcol) head += cnt * head_mid; - else if (max_head_vcol > vcol + head_prev + prev_rem) + else if (width2 > 0 + && max_head_vcol > vcol + head_prev + prev_rem) head += (max_head_vcol - (vcol + head_prev + prev_rem) + width2 - 1) / width2 * head_mid; else if (max_head_vcol < 0) diff --git a/src/testdir/test_scroll_opt.vim b/src/testdir/test_scroll_opt.vim index 390a8b59a2..6ece601f7a 100644 --- a/src/testdir/test_scroll_opt.vim +++ b/src/testdir/test_scroll_opt.vim @@ -2090,4 +2090,42 @@ func Test_scrolloffpad_with_folds() call StopVimInTerminal(buf) let &termwinsize = save_termwinsize endfunc + +" Resizing to "textoff" after 'smoothscroll' skips part of a wrapped line must +" not crash. +func Test_smoothscroll_textoff_showbreak() + CheckOption smoothscroll + + let donefile = 'XTest_crash_textoff_showbreak_done' + defer delete(donefile) + let lines =<< trim END + set noswapfile + + set scrolloff=0 + set lines=12 columns=40 + + call setline(1, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa') + set number wrap smoothscroll showbreak=> + vsplit + + let textoff = getwininfo(win_getid())[0].textoff + execute "normal! 0\" + redraw + execute 'vertical resize' textoff + redraw + call writefile(['done'], 'XTest_crash_textoff_showbreak_done') + END + call writefile(lines, 'XTest_crash_textoff_showbreak', 'D') + + let buf = 0 + let buf = term_start([GetVimProg(), '--clean'], #{term_rows: 24, term_cols: 80}) + call TermWait(buf, 200) + call term_sendkeys(buf, ":source XTest_crash_textoff_showbreak\") + call WaitForAssert({-> assert_true(filereadable(donefile))}) + let status = term_getstatus(buf) + call assert_equal('running', status) + call assert_true(filereadable(donefile)) + call StopVimInTerminal(buf) +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c index 4a4b69288b..7d09dfddd1 100644 --- a/src/version.c +++ b/src/version.c @@ -734,6 +734,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 362, /**/ 361, /**/