mirror of
https://github.com/neovim/neovim.git
synced 2026-08-28 01:51:52 +00:00
fix(ui): don't crash if maximum UI count reached (#37636)
This commit is contained in:
@@ -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);
|
"UI already attached to channel: %" PRId64, channel_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!ui_can_attach_more()) {
|
||||||
|
api_set_error(err, kErrorTypeException, "Maximum UI count reached");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (width <= 0 || height <= 0) {
|
if (width <= 0 || height <= 0) {
|
||||||
api_set_error(err, kErrorTypeValidation,
|
api_set_error(err, kErrorTypeValidation, "Expected width > 0 and height > 0");
|
||||||
"Expected width > 0 and height > 0");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
RemoteUI *ui = xcalloc(1, sizeof(RemoteUI));
|
RemoteUI *ui = xcalloc(1, sizeof(RemoteUI));
|
||||||
|
|||||||
@@ -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)
|
void ui_attach_impl(RemoteUI *ui, uint64_t chanid)
|
||||||
{
|
{
|
||||||
if (ui_count == MAX_UI_COUNT) {
|
if (ui_count >= MAX_UI_COUNT) {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
if (!ui->ui_ext[kUIMultigrid] && !ui->ui_ext[kUIFloatDebug]
|
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();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,23 @@ describe('nvim_ui_attach()', function()
|
|||||||
pcall_err(request, 'nvim_ui_attach', 40, 10, { rgb = false })
|
pcall_err(request, 'nvim_ui_attach', 40, 10, { rgb = false })
|
||||||
)
|
)
|
||||||
end)
|
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)
|
end)
|
||||||
|
|
||||||
describe('nvim_ui_send', function()
|
describe('nvim_ui_send', function()
|
||||||
@@ -100,9 +117,9 @@ describe('nvim_ui_send', function()
|
|||||||
poke_eventloop()
|
poke_eventloop()
|
||||||
|
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
^ |
|
^ |
|
||||||
{1:~ }|*8
|
{1:~ }|*8
|
||||||
|
|
|
|
||||||
]])
|
]])
|
||||||
|
|
||||||
eq('Hello world', table.concat(read_data))
|
eq('Hello world', table.concat(read_data))
|
||||||
@@ -130,9 +147,9 @@ describe('nvim_ui_send', function()
|
|||||||
poke_eventloop()
|
poke_eventloop()
|
||||||
|
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
^ |
|
^ |
|
||||||
{1:~ }|*8
|
{1:~ }|*8
|
||||||
|
|
|
|
||||||
]])
|
]])
|
||||||
|
|
||||||
eq('', table.concat(read_data))
|
eq('', table.concat(read_data))
|
||||||
|
|||||||
@@ -299,7 +299,7 @@ end)
|
|||||||
|
|
||||||
describe('--embed --listen UI', function()
|
describe('--embed --listen UI', function()
|
||||||
it('waits for connection on listening address', 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()
|
clear()
|
||||||
local child_server = assert(n.new_pipename())
|
local child_server = assert(n.new_pipename())
|
||||||
fn.jobstart({
|
fn.jobstart({
|
||||||
|
|||||||
Reference in New Issue
Block a user