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 <tomtomjhj@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Jaehwang Jung
2026-04-19 18:32:55 +00:00
committed by Christian Brabandt
parent 336533b355
commit 0e31fb024c
3 changed files with 42 additions and 1 deletions
+2 -1
View File
@@ -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)
+38
View File
@@ -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\<C-E>"
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\<CR>")
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
+2
View File
@@ -734,6 +734,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
362,
/**/
361,
/**/