fix(ui): don't crash if maximum UI count reached (#37636)

This commit is contained in:
zeertzjq
2026-01-31 21:09:06 +08:00
committed by GitHub
parent 1e6c4ea896
commit 7ca3a56258
4 changed files with 36 additions and 11 deletions

View File

@@ -162,10 +162,13 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, Dict opt
"UI already attached to channel: %" PRId64, channel_id);
return;
}
if (!ui_can_attach_more()) {
api_set_error(err, kErrorTypeException, "Maximum UI count reached");
return;
}
if (width <= 0 || height <= 0) {
api_set_error(err, kErrorTypeValidation,
"Expected width > 0 and height > 0");
api_set_error(err, kErrorTypeValidation, "Expected width > 0 and height > 0");
return;
}
RemoteUI *ui = xcalloc(1, sizeof(RemoteUI));

View File

@@ -371,9 +371,14 @@ void do_autocmd_uienter_all(void)
}
}
bool ui_can_attach_more(void)
{
return ui_count < MAX_UI_COUNT;
}
void ui_attach_impl(RemoteUI *ui, uint64_t chanid)
{
if (ui_count == MAX_UI_COUNT) {
if (ui_count >= MAX_UI_COUNT) {
abort();
}
if (!ui->ui_ext[kUIMultigrid] && !ui->ui_ext[kUIFloatDebug]
@@ -419,7 +424,7 @@ void ui_detach_impl(RemoteUI *ui, uint64_t chanid)
}
}
if (shift_index == MAX_UI_COUNT) {
if (shift_index >= MAX_UI_COUNT) {
abort();
}

View File

@@ -71,6 +71,23 @@ describe('nvim_ui_attach()', function()
pcall_err(request, 'nvim_ui_attach', 40, 10, { rgb = false })
)
end)
it('does not crash if maximum UI count is reached', function()
t.skip(t.is_os('win'), 'n.connect() hangs on Windows')
local server = api.nvim_get_vvar('servername')
local screens = {} --- @type test.functional.ui.screen[]
for i = 1, 16 do
screens[i] = Screen.new(nil, nil, nil, n.connect(server))
end
eq(
-- 0 is kErrorTypeException
{ false, { 0, 'Maximum UI count reached' } },
{ n.connect(server):request('nvim_ui_attach', 80, 24, {}) }
)
for i = 1, 16 do
screens[i]:detach()
end
end)
end)
describe('nvim_ui_send', function()
@@ -100,9 +117,9 @@ describe('nvim_ui_send', function()
poke_eventloop()
screen:expect([[
^ |
{1:~ }|*8
|
^ |
{1:~ }|*8
|
]])
eq('Hello world', table.concat(read_data))
@@ -130,9 +147,9 @@ describe('nvim_ui_send', function()
poke_eventloop()
screen:expect([[
^ |
{1:~ }|*8
|
^ |
{1:~ }|*8
|
]])
eq('', table.concat(read_data))

View File

@@ -299,7 +299,7 @@ end)
describe('--embed --listen UI', function()
it('waits for connection on listening address', function()
t.skip(t.is_os('win'))
t.skip(t.is_os('win'), 'n.connect() hangs on Windows')
clear()
local child_server = assert(n.new_pipename())
fn.jobstart({