Commit: patch 9.2.0284: tabpanel: crash when tabpanel expression returns variable line count

2 views
Skip to first unread message

Christian Brabandt

unread,
Apr 2, 2026, 1:47:15 PM (12 hours ago) Apr 2
to vim...@googlegroups.com
patch 9.2.0284: tabpanel: crash when tabpanel expression returns variable line count

Commit: https://github.com/vim/vim/commit/b2fbb7c32de0e36cfc626b2948ae5ac80b8cbac3
Author: Christian Brabandt <c...@256bit.org>
Date: Thu Apr 2 17:37:58 2026 +0000

patch 9.2.0284: tabpanel: crash when tabpanel expression returns variable line count

Problem: When a tabpanel expression returns a different number of lines on
successive evaluations, the computed row offset can become negative,
causing screen_fill() to receive an invalid start_row and crash
(after v9.1.1391).
Solution: Clamp the row argument in screen_fill_tailing_area() to zero,
add a safety check in screen_fill() for negative start_row
(Michał Majchrowicz)

Supported by AI

Co-authored-by: Michał Majchrowicz <mmajch...@afine.com>
Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/src/screen.c b/src/screen.c
index eeee319bf..3e6fd3f4c 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -2498,6 +2498,7 @@ screen_fill(
if (end_col > screen_Columns) // safety check
end_col = screen_Columns;
if (ScreenLines == NULL
+ || start_row < 0 // should not happen
|| start_row >= end_row
|| start_col >= end_col) // nothing to do
return;
diff --git a/src/tabpanel.c b/src/tabpanel.c
index 9db957dda..2a6dbe831 100644
--- a/src/tabpanel.c
+++ b/src/tabpanel.c
@@ -544,7 +544,7 @@ do_by_tplmode(
}

// fill the area of TabPanelFill.
- screen_fill_tailing_area(tplmode, row - args.offsetrow, args.maxrow,
+ screen_fill_tailing_area(tplmode, MAX(row - args.offsetrow, 0), args.maxrow,
args.col_start, args.col_end, attr_tplf);
}

diff --git a/src/testdir/test_tabpanel.vim b/src/testdir/test_tabpanel.vim
index 0329dd7a4..f983e2b37 100644
--- a/src/testdir/test_tabpanel.vim
+++ b/src/testdir/test_tabpanel.vim
@@ -892,4 +892,35 @@ func Test_tabpanel_large_columns()
call assert_fails(':set tabpanelopt=columns:-1', 'E474:')
endfunc

+func Test_tabpanel_variable_height()
+ CheckFeature tabpanel
+
+ let save_lines = &lines
+ let save_showtabpanel = &showtabpanel
+ let save_tabpanel = &tabpanel
+
+ set lines=10
+ tabnew | tabnew | tabnew | tabnew | tabnew
+
+ let g:tpl_n = 0
+ func! GetTpl() abort
+ let g:tpl_n += 1
+ return g:tpl_n <= 5 ? "x
x" : "x"
+ endfunc
+
+ set showtabpanel=2
+ let &tabpanel = "%!GetTpl()"
+
+ " Should not crash
+ redraw!
+
+ " Cleanup
+ let &tabpanel = save_tabpanel
+ let &showtabpanel = save_showtabpanel
+ let &lines = save_lines
+ delfunc GetTpl
+ unlet g:tpl_n
+ %bwipeout!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 964ce05f7..ebb473294 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 */
+/**/
+ 284,
/**/
283,
/**/
Reply all
Reply to author
Forward
0 new messages