mirror of
https://github.com/neovim/neovim
synced 2025-07-16 09:11:51 +00:00
fix(lua): SIGSEGV in luv callback with error(nil) #32595
Problem:
luv callback `vim.uv.new_timer():start(0, 0, function() error() end)`
causes SIGSEGV, since `xstrdup` gets NULL from `lua_tostring`.
Similar to: a5b1b83a26
Solution:
Check NULL before `xstrdup`.
This commit is contained in:
@ -221,7 +221,7 @@ static int nlua_fast_cfpcall(lua_State *lstate, int nargs, int nresult, int flag
|
|||||||
const char *error = lua_tostring(lstate, -1);
|
const char *error = lua_tostring(lstate, -1);
|
||||||
|
|
||||||
multiqueue_put(main_loop.events, nlua_luv_error_event,
|
multiqueue_put(main_loop.events, nlua_luv_error_event,
|
||||||
xstrdup(error), (void *)(intptr_t)kCallback);
|
error != NULL ? xstrdup(error) : NULL, (void *)(intptr_t)kCallback);
|
||||||
lua_pop(lstate, 1); // error message
|
lua_pop(lstate, 1); // error message
|
||||||
retval = -status;
|
retval = -status;
|
||||||
} else { // LUA_OK
|
} else { // LUA_OK
|
||||||
|
@ -159,4 +159,39 @@ describe('vim.uv', function()
|
|||||||
it("is equal to require('luv')", function()
|
it("is equal to require('luv')", function()
|
||||||
eq(true, exec_lua("return vim.uv == require('luv')"))
|
eq(true, exec_lua("return vim.uv == require('luv')"))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('non-string error() #32595', function()
|
||||||
|
local screen = Screen.new(50, 10)
|
||||||
|
exec_lua(function()
|
||||||
|
local timer = assert(vim.uv.new_timer())
|
||||||
|
timer:start(0, 0, function()
|
||||||
|
timer:close()
|
||||||
|
error(nil)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
local s = [[
|
||||||
|
|
|
||||||
|
{1:~ }|*5
|
||||||
|
{3: }|
|
||||||
|
{9:Error executing callback:} |
|
||||||
|
{9:[NULL]} |
|
||||||
|
{6:Press ENTER or type command to continue}^ |
|
||||||
|
]]
|
||||||
|
screen:expect(s)
|
||||||
|
feed('<cr>')
|
||||||
|
n.assert_alive()
|
||||||
|
screen:expect([[
|
||||||
|
^ |
|
||||||
|
{1:~ }|*8
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
exec_lua(function()
|
||||||
|
vim.uv.fs_stat('non-existent-file', function()
|
||||||
|
error(nil)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
screen:expect(s)
|
||||||
|
feed('<cr>')
|
||||||
|
n.assert_alive()
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
Reference in New Issue
Block a user