diff options
author | 林玮 (Jade Lin) <linw1995@icloud.com> | 2025-01-18 16:40:40 +0800 |
---|---|---|
committer | Lewis Russell <me@lewisr.dev> | 2025-01-18 19:08:50 +0000 |
commit | a5b1b83a2693ffa7a5a0a22b3693d36ea60051be (patch) | |
tree | 40729b75875ad8e1f056b05b0ffb3dfb6974c7c5 | |
parent | 51ccd12b3dbc50300e83f503426abbcb605efcea (diff) | |
download | rneovim-a5b1b83a2693ffa7a5a0a22b3693d36ea60051be.tar.gz rneovim-a5b1b83a2693ffa7a5a0a22b3693d36ea60051be.tar.bz2 rneovim-a5b1b83a2693ffa7a5a0a22b3693d36ea60051be.zip |
fix(lua): prevent SIGSEGV when lua error is NULL in libuv_worker
Problem:
Calling `xstrdup` with a NULL pointer causes a SIGSEGV if `lua_tostring` returns
NULL in `nlua_luv_thread_common_cfpcall`.
Crash stack trace:
- `_platform_strlen` → `xstrdup` (memory.c:469)
- `nlua_luv_thread_common_cfpcall` (executor.c:281)
Solution:
Check if `lua_tostring` returns NULL and pass NULL to `event_create` to avoid the crash.
-rw-r--r-- | src/nvim/lua/executor.c | 3 | ||||
-rw-r--r-- | test/functional/lua/thread_spec.lua | 20 |
2 files changed, 21 insertions, 2 deletions
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index 68d3af6074..a5b48a5d5e 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -276,10 +276,9 @@ static int nlua_luv_thread_common_cfpcall(lua_State *lstate, int nargs, int nres #endif } const char *error = lua_tostring(lstate, -1); - loop_schedule_deferred(&main_loop, event_create(nlua_luv_error_event, - xstrdup(error), + error != NULL ? xstrdup(error) : NULL, (void *)(intptr_t)(is_callback ? kThreadCallback : kThread))); diff --git a/test/functional/lua/thread_spec.lua b/test/functional/lua/thread_spec.lua index 310705fd97..8ca4bdc4f5 100644 --- a/test/functional/lua/thread_spec.lua +++ b/test/functional/lua/thread_spec.lua @@ -19,6 +19,26 @@ describe('thread', function() screen = Screen.new(50, 10) end) + it('handle non-string error', function() + exec_lua [[ + local thread = vim.uv.new_thread(function() + error() + end) + vim.uv.thread_join(thread) + ]] + + screen:expect([[ + | + {1:~ }|*5 + {3: }| + {9:Error in luv thread:} | + {9:[NULL]} | + {6:Press ENTER or type command to continue}^ | + ]]) + feed('<cr>') + assert_alive() + end) + it('entry func is executed in protected mode', function() exec_lua [[ local thread = vim.uv.new_thread(function() |