patch 9.2.0180: possible crash with winminheight=0

Commit: 
https://github.com/vim/vim/commit/a5d9654620648ea6d3f2f8dc2a3e42de219cf860
Author: Hirohito Higashi <[email protected]>
Date:   Mon Mar 16 21:41:47 2026 +0000

    patch 9.2.0180: possible crash with winminheight=0
    
    Problem:  possible crash with winminheight=0
              (Emilien Breton)
    Solution: Use <= instead of < when checking reserved room in
              frame_setheight() to correctly handle the zero-height
              boundary case (Hirohito Higashi).
    
    In frame_setheight(), when shrinking the current window and the only
    other window has 'winfixheight' with 'winminheight'=0, room_reserved
    was not cleared because the condition used '<' instead of '<='.
    The freed rows were discarded, leaving fr_height sum less than
    topframe fr_height.  Subsequent resize operations then computed a
    wrong room_cmdline that expanded topframe beyond the screen, causing
    a crash.
    
    fixes:  #19706
    closes: #19712
    
    Signed-off-by: Hirohito Higashi <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/src/testdir/test_window_cmd.vim b/src/testdir/test_window_cmd.vim
index 02e6fcbc3..1832a9790 100644
--- a/src/testdir/test_window_cmd.vim
+++ b/src/testdir/test_window_cmd.vim
@@ -2374,4 +2374,68 @@ func Test_resize_from_another_tabpage()
   call StopVimInTerminal(buf)
 endfunc
 
+" When shrinking a window and the only other window has 'winfixheight'
+" with 'winminheight'=0, freed rows must go to the wfh window.
+func Test_winfixheight_resize_wmh_zero()
+  set winminheight=0 laststatus=0
+
+  let id1 = win_getid()
+  copen
+  let id2 = win_getid()
+  wincmd w
+  wincmd _
+  let wi1 = getwininfo(id1)[0]
+  let wi2 = getwininfo(id2)[0]
+  let exp = &lines - wi1.status_height - wi2.height - wi2.status_height - &ch
+  call assert_equal([exp, 1], [wi1.height, wi1.status_height])
+  call assert_equal([0, 0], [wi2.height, wi2.status_height])
+
+  wincmd w  " enter qf (height 0 -> 1)
+  let wi1 = getwininfo(id1)[0]
+  let wi2 = getwininfo(id2)[0]
+  let exp = &lines - wi1.status_height - wi2.height - wi2.status_height - &ch
+  call assert_equal(exp, wi1.height)
+  call assert_equal(1, wi2.height)
+
+  wincmd w
+  " Freed rows must go to qf (wfh, only other window).
+  " Before the fix, the rows were lost (fr_height sum < topframe fr_height),
+  " resulting in wrong window heights in subsequent operations.
+  1wincmd _
+  let wi1 = getwininfo(id1)[0]
+  let wi2 = getwininfo(id2)[0]
+  call assert_equal(1, wi1.height)
+  let exp = &lines - wi1.height - wi1.status_height - &ch
+  call assert_equal(exp, wi2.height)
+
+  wincmd w
+  99wincmd +
+  let wi1 = getwininfo(id1)[0]
+  let wi2 = getwininfo(id2)[0]
+  call assert_equal(0, wi1.height)
+  let exp = &lines - wi1.height - wi1.status_height - &ch
+  call assert_equal(exp, wi2.height)
+
+  99wincmd -
+  let wi1 = getwininfo(id1)[0]
+  let wi2 = getwininfo(id2)[0]
+  let exp = &lines - wi1.status_height - wi2.height - &ch
+  call assert_equal(exp, wi1.height)
+  call assert_equal(1, wi2.height)
+
+  " The original bug caused a crash here, but could not be reproduced in the
+  " test.  Kept as-is, though it has no particular significance.
+  wincmd w
+  call feedkeys("999i\<CR>\<Esc>", 'tx')
+  call feedkeys("ggMi" .. repeat("\<CR>", 99) .. "\<Esc>", 'tx')
+  let wi1 = getwininfo(id1)[0]
+  let wi2 = getwininfo(id2)[0]
+  let exp = &lines - wi1.status_height - wi2.height - &ch
+  call assert_equal(exp, wi1.height)
+  call assert_equal(1, wi2.height)
+
+  cclose
+  set winminheight& laststatus&
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index fe4fe69b2..8889f69af 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 */
+/**/
+    180,
 /**/
     179,
 /**/
diff --git a/src/window.c b/src/window.c
index cee40b79e..4b6626cc3 100644
--- a/src/window.c
+++ b/src/window.c
@@ -6650,7 +6650,7 @@ frame_setheight(frame_T *curfrp, int height)
            room_reserved = room + room_cmdline - height;
        // If there is only a 'winfixheight' window and making the
        // window smaller, need to make the other window taller.
-       if (take < 0 && room - curfrp->fr_height < room_reserved)
+       if (take < 0 && room - curfrp->fr_height <= room_reserved)
            room_reserved = 0;
 
        if (take > 0 && room_cmdline > 0)

-- 
-- 
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/E1w2FkH-008vGH-Es%40256bit.org.

Raspunde prin e-mail lui