From d672f0f494a6fb5880d3df95af3275ed118f626d Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 15 Apr 2026 07:59:17 +0800 Subject: [PATCH] vim-patch:partial:9.2.0348: potential buffer underrun when setting statusline like option (#39063) Problem: potential buffer underrun when settings statusline like option (q1uf3ng) Solution: Validate that p > out before accessing p[-1] closes: vim/vim#19961 https://github.com/vim/vim/commit/91b402f57575ed33649285043a3c631701165f4a Co-authored-by: Christian Brabandt (cherry picked from commit e0eb967f8a68d942165c9a8f04920494a5abfc1c) --- src/nvim/statusline.c | 2 +- test/old/testdir/test_cmdline.vim | 10 ++++++++++ test/old/testdir/test_options.vim | 8 +++++--- test/old/testdir/test_statusline.vim | 10 ++++++++++ test/old/testdir/test_tabline.vim | 10 ++++++++++ 5 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c index 308da4af67..d7c289f43c 100644 --- a/src/nvim/statusline.c +++ b/src/nvim/statusline.c @@ -1375,7 +1375,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op break; } fmt_p++; - if (reevaluate) { + if (reevaluate && out_p > out) { out_p[-1] = NUL; // remove the % at the end of %{% expr %} } else { *out_p = NUL; diff --git a/test/old/testdir/test_cmdline.vim b/test/old/testdir/test_cmdline.vim index f13413fb8d..99efd781f8 100644 --- a/test/old/testdir/test_cmdline.vim +++ b/test/old/testdir/test_cmdline.vim @@ -5248,4 +5248,14 @@ func Test_breaklist_args_fails() call assert_fails(':breaklist extra', 'E488:') endfunc +func Test_rulerformat_empty() + set ruler rulerformat=%!'%{}%' + try + redraw + catch + endtry + set ruler& + set rulerformat& +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/test/old/testdir/test_options.vim b/test/old/testdir/test_options.vim index d2f0071017..2b6ae9101c 100644 --- a/test/old/testdir/test_options.vim +++ b/test/old/testdir/test_options.vim @@ -863,9 +863,6 @@ func Test_set_option_errors() call assert_fails('set commentstring=x', 'E537:') call assert_fails('let &commentstring = "x"', 'E537:') call assert_fails('set complete=x', 'E539:') - call assert_fails('set rulerformat=%-', 'E539:') - call assert_fails('set rulerformat=%(', 'E542:') - call assert_fails('set rulerformat=%15(%%', 'E542:') " Test for 'statusline' errors call assert_fails('set statusline=%^', 'E539:') " Nvim: supports %$ @@ -883,6 +880,11 @@ func Test_set_option_errors() call assert_fails('set tabline=%(', 'E542:') call assert_fails('set tabline=%)', 'E542:') + " Test for 'rulerformat' errors + call assert_fails('set rulerformat=%-', 'E539:') + call assert_fails('set rulerformat=%(', 'E542:') + call assert_fails('set rulerformat=%15(%%', 'E542:') + if has('cursorshape') " This invalid value for 'guicursor' used to cause Vim to crash. call assert_fails('set guicursor=i-ci,r-cr:h', 'E545:') diff --git a/test/old/testdir/test_statusline.vim b/test/old/testdir/test_statusline.vim index b5ca5d3666..d50fa2edc6 100644 --- a/test/old/testdir/test_statusline.vim +++ b/test/old/testdir/test_statusline.vim @@ -731,4 +731,14 @@ func Test_statusline_singlebyte_negative() let [&columns, &ls, &stl, &enc] = [_columns, _ls, _stl, _enc] endfunc +func Test_statusline_empty() + set laststatus=2 statusline=%!'%{}%' + try + redraw! + catch + endtry + set laststatus& + set statusline& +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/test/old/testdir/test_tabline.vim b/test/old/testdir/test_tabline.vim index 4de6f845cb..d1ec2a64fe 100644 --- a/test/old/testdir/test_tabline.vim +++ b/test/old/testdir/test_tabline.vim @@ -232,4 +232,14 @@ func Test_tabline_truncated_double_width() call nvim_set_hl(0, 'TabLine', save_TabLine) endfunc +func Test_tabline_empty() + set showtabline=2 tabline=%!'%{}%' + try + redraw! + catch + endtry + set showtabline& + set tabline& +endfunc + " vim: shiftwidth=2 sts=2 expandtab