mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 11:28:22 +00:00
fix(messages)!: vim.ui_attach message callbacks are unsafe
Problem: Lua callbacks for "msg_show" events with vim.ui_attach() are executed when it is not safe. Solution: Disallow non-fast API calls for "msg_show" event callbacks. Automatically detach callback after excessive errors. Make sure fast APIs do not modify Nvim state.
This commit is contained in:
@@ -25,8 +25,6 @@ local command = n.command
|
||||
local write_file = t.write_file
|
||||
local api = n.api
|
||||
local sleep = vim.uv.sleep
|
||||
local matches = t.matches
|
||||
local pcall_err = t.pcall_err
|
||||
local assert_alive = n.assert_alive
|
||||
local poke_eventloop = n.poke_eventloop
|
||||
local feed = n.feed
|
||||
@@ -227,72 +225,6 @@ describe('listing functions using :function', function()
|
||||
exec_capture(('function <lambda>%s'):format(num))
|
||||
)
|
||||
end)
|
||||
|
||||
it('does not crash if another function is deleted while listing', function()
|
||||
local _ = Screen.new(80, 24)
|
||||
matches(
|
||||
'Vim%(function%):E454: Function list was modified$',
|
||||
pcall_err(
|
||||
exec_lua,
|
||||
[=[
|
||||
vim.cmd([[
|
||||
func Func1()
|
||||
endfunc
|
||||
func Func2()
|
||||
endfunc
|
||||
func Func3()
|
||||
endfunc
|
||||
]])
|
||||
|
||||
local ns = vim.api.nvim_create_namespace('test')
|
||||
|
||||
vim.ui_attach(ns, { ext_messages = true }, function(event, _, content)
|
||||
if event == 'msg_show' and content[1][2] == 'function Func1()' then
|
||||
vim.cmd('delfunc Func3')
|
||||
end
|
||||
end)
|
||||
|
||||
vim.cmd('function')
|
||||
|
||||
vim.ui_detach(ns)
|
||||
]=]
|
||||
)
|
||||
)
|
||||
assert_alive()
|
||||
end)
|
||||
|
||||
it('does not crash if the same function is deleted while listing', function()
|
||||
local _ = Screen.new(80, 24)
|
||||
matches(
|
||||
'Vim%(function%):E454: Function list was modified$',
|
||||
pcall_err(
|
||||
exec_lua,
|
||||
[=[
|
||||
vim.cmd([[
|
||||
func Func1()
|
||||
endfunc
|
||||
func Func2()
|
||||
endfunc
|
||||
func Func3()
|
||||
endfunc
|
||||
]])
|
||||
|
||||
local ns = vim.api.nvim_create_namespace('test')
|
||||
|
||||
vim.ui_attach(ns, { ext_messages = true }, function(event, _, content)
|
||||
if event == 'msg_show' and content[1][2] == 'function Func1()' then
|
||||
vim.cmd('delfunc Func2')
|
||||
end
|
||||
end)
|
||||
|
||||
vim.cmd('function')
|
||||
|
||||
vim.ui_detach(ns)
|
||||
]=]
|
||||
)
|
||||
)
|
||||
assert_alive()
|
||||
end)
|
||||
end)
|
||||
|
||||
it('no double-free in garbage collection #16287', function()
|
||||
|
Reference in New Issue
Block a user