mirror of
https://github.com/vim/vim.git
synced 2026-05-28 00:21:37 +02:00
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 <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
e06d084735
commit
a5d9654620
@@ -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
|
||||
|
||||
@@ -734,6 +734,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
180,
|
||||
/**/
|
||||
179,
|
||||
/**/
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user