fix(pum): crash when resizing grid with pumborder set (#36404)

Problem: Grid size check didn't account for border_width, causing
row index out of bounds when drawing bordered popup menu.

Solution: Check grid.rows against pum_height + border_width.
This commit is contained in:
glepnir
2025-11-10 07:07:25 +08:00
committed by GitHub
parent a0678a5849
commit 76fdd9b882
2 changed files with 36 additions and 1 deletions

View File

@@ -660,7 +660,8 @@ void pum_redraw(void)
pum_invalid = false;
must_redraw_pum = false;
if (!pum_grid.chars || pum_grid.rows != pum_height || pum_grid.cols != grid_width) {
if (!pum_grid.chars || pum_grid.rows != pum_height + border_width
|| pum_grid.cols != grid_width + border_width) {
grid_alloc(&pum_grid, pum_height + border_width, grid_width + border_width,
!invalid_grid, false);
ui_call_grid_resize(pum_grid.handle, pum_grid.cols, pum_grid.rows);

View File

@@ -14,6 +14,7 @@ local eq = t.eq
local pcall_err = t.pcall_err
local exec_lua = n.exec_lua
local exec = n.exec
local poke_eventloop = n.poke_eventloop
describe('ui/ext_popupmenu', function()
local screen
@@ -9343,6 +9344,39 @@ describe('builtin popupmenu', function()
]])
end
end)
it("no crash when 'pumborder' set #36337", function()
command('set autocomplete pumborder=rounded complete=o cot=popup,menuone,noinsert')
command('set columns=50 lines=20')
exec_lua(function()
local list1 = {
{ abbr = 'array: ', info = '', kind = 'Field', word = 'array: ' },
{ abbr = 'arrays: ', info = '', kind = 'Field', word = 'arrays: ' },
}
local list2 = {
{ abbr = 'match ', info = '', kind = 'Keyword', word = 'match ' },
{ abbr = 'throw ', info = '', kind = 'Keyword', word = 'throw ' },
{ abbr = 'array: ', info = '', kind = 'Field', word = 'array: ' },
{ abbr = 'arrays: ', info = '', kind = 'Field', word = 'arrays: ' },
}
_G.fake_omni = function(_, _)
local line = vim.api.nvim_get_current_line()
if line:find('%s%)$') then
vim.schedule(function()
vim.fn.complete(25, list1)
vim.fn.complete(25, list2)
end)
end
return -2
end
vim.opt.omnifunc = 'v:lua.fake_omni'
vim.api.nvim_buf_set_lines(0, 0, -1, true, { '<?php', 'array_intersect_key($x)' })
vim.cmd.normal('G$')
end)
feed('i, ')
poke_eventloop()
assert_alive()
eq({ 4, 1 }, { #fn.complete_info({ 'items' }).items, fn.pumvisible() })
end)
end)
end