diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index 124fce58b6..30d3f26f0e 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -451,10 +452,19 @@ static int nlua_wait(lua_State *lstate) return luaL_error(lstate, e_fast_api_disabled, "vim.wait"); } - intptr_t timeout = luaL_checkinteger(lstate, 1); - if (timeout < 0) { + double timeout_number = luaL_checknumber(lstate, 1); + if (timeout_number < 0) { return luaL_error(lstate, "timeout must be >= 0"); } + int64_t timeout; + if (isinf(timeout_number) || timeout_number > (double)INT64_MAX) { + timeout = INT64_MAX; + } else { + if (isnan(timeout_number) || timeout_number != trunc(timeout_number)) { + return luaL_error(lstate, "timeout has no integer representation"); + } + timeout = (int64_t)timeout_number; + } int lua_top = lua_gettop(lstate); @@ -510,7 +520,7 @@ static int nlua_wait(lua_State *lstate) LOOP_PROCESS_EVENTS_UNTIL(&main_loop, loop_events, - (int)timeout, + timeout, got_int || (is_function ? nlua_wait_condition(lstate, &pcall_status, &callback_result, diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua index 73b393f11a..6aef76f476 100644 --- a/test/functional/lua/vim_spec.lua +++ b/test/functional/lua/vim_spec.lua @@ -2451,7 +2451,8 @@ stack traceback: exec_lua([[ function _G.Wait() vim.rpcnotify(vim.g.channel, 'ready') - local _, interrupted = vim.wait(4000) + -- handles math.huge #36854 + local _, interrupted = vim.wait(math.huge) vim.rpcnotify(vim.g.channel, 'wait', interrupted) end ]]) @@ -2465,7 +2466,7 @@ stack traceback: exec_lua([[ function _G.Wait() vim.rpcnotify(vim.g.channel, 'ready') - local _, interrupted = vim.wait(4000, function() end) + local _, interrupted = vim.wait(math.huge, function() end) vim.rpcnotify(vim.g.channel, 'wait', interrupted) end ]])