patch 9.2.0362: division by zero with smoothscroll and small windows

Commit: 
https://github.com/vim/vim/commit/0e31fb024c846e36bb0d26d01ff179a0d1b3eae4
Author: Jaehwang Jung <[email protected]>
Date:   Sun Apr 19 18:32:55 2026 +0000

    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 <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/src/charset.c b/src/charset.c
index 8ad768d35..bf7c59620 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 390a8b59a..6ece601f7 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\<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
diff --git a/src/version.c b/src/version.c
index 4a4b69288..7d09dfddd 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,
 /**/

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/vim_dev/E1wEX8l-00AvWZ-82%40256bit.org.

Raspunde prin e-mail lui