From fe1e2eff062605f7e617885011160a678822fd0c Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 8 Dec 2024 09:25:43 +0800 Subject: fix(lua): avoid vim._with() double-free with cmdmod (#31505) --- src/nvim/lua/stdlib.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/lua') diff --git a/src/nvim/lua/stdlib.c b/src/nvim/lua/stdlib.c index e719d99640..5ebff3a809 100644 --- a/src/nvim/lua/stdlib.c +++ b/src/nvim/lua/stdlib.c @@ -619,6 +619,7 @@ static int nlua_with(lua_State *L) int rets = 0; cmdmod_T save_cmdmod = cmdmod; + CLEAR_FIELD(cmdmod); cmdmod.cmod_flags = flags; apply_cmdmod(&cmdmod); -- cgit From 6bf2a6fc5bb395b67c88cb26d332f882a106c7ab Mon Sep 17 00:00:00 2001 From: luukvbaal Date: Tue, 17 Dec 2024 13:12:22 +0100 Subject: refactor(api): always use TRY_WRAP #31600 Problem: Two separate try/end wrappers, that only marginally differ by restoring a few variables. Wrappers that don't restore previous state are dangerous to use in "api-fast" functions. Solution: Remove wrappers that don't restore the previous state. Always use TRY_WRAP. --- src/nvim/lua/stdlib.c | 48 +++++++++++++++++++++--------------------------- 1 file changed, 21 insertions(+), 27 deletions(-) (limited to 'src/nvim/lua') diff --git a/src/nvim/lua/stdlib.c b/src/nvim/lua/stdlib.c index 5ebff3a809..4de25f4265 100644 --- a/src/nvim/lua/stdlib.c +++ b/src/nvim/lua/stdlib.c @@ -623,38 +623,32 @@ static int nlua_with(lua_State *L) cmdmod.cmod_flags = flags; apply_cmdmod(&cmdmod); - if (buf || win) { - try_start(); - } - - aco_save_T aco; - win_execute_T win_execute_args; Error err = ERROR_INIT; + TRY_WRAP(&err, { + aco_save_T aco; + win_execute_T win_execute_args; - if (win) { - tabpage_T *tabpage = win_find_tabpage(win); - if (!win_execute_before(&win_execute_args, win, tabpage)) { - goto end; + if (win) { + tabpage_T *tabpage = win_find_tabpage(win); + if (!win_execute_before(&win_execute_args, win, tabpage)) { + goto end; + } + } else if (buf) { + aucmd_prepbuf(&aco, buf); } - } else if (buf) { - aucmd_prepbuf(&aco, buf); - } - int s = lua_gettop(L); - lua_pushvalue(L, 2); - status = lua_pcall(L, 0, LUA_MULTRET, 0); - rets = lua_gettop(L) - s; + int s = lua_gettop(L); + lua_pushvalue(L, 2); + status = lua_pcall(L, 0, LUA_MULTRET, 0); + rets = lua_gettop(L) - s; - if (win) { - win_execute_after(&win_execute_args); - } else if (buf) { - aucmd_restbuf(&aco); - } - -end: - if (buf || win) { - try_end(&err); - } + if (win) { + win_execute_after(&win_execute_args); + } else if (buf) { + aucmd_restbuf(&aco); + } + end:; + }); undo_cmdmod(&cmdmod); cmdmod = save_cmdmod; -- cgit From 2a7d0ed6145bf3f8b139c2694563f460f829813a Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 23 Dec 2024 05:43:52 -0800 Subject: refactor: iwyu #31637 Result of `make iwyu` (after some "fixups"). --- src/nvim/lua/api_wrappers.c | 30 +++++++++++++++--------------- src/nvim/lua/converter.c | 1 + src/nvim/lua/executor.c | 3 ++- src/nvim/lua/executor.h | 2 +- src/nvim/lua/secure.c | 2 +- src/nvim/lua/spell.c | 2 +- src/nvim/lua/stdlib.c | 2 ++ src/nvim/lua/treesitter.c | 3 +-- src/nvim/lua/xdiff.c | 1 + 9 files changed, 25 insertions(+), 21 deletions(-) (limited to 'src/nvim/lua') diff --git a/src/nvim/lua/api_wrappers.c b/src/nvim/lua/api_wrappers.c index 36847d1fc9..447ba846b4 100644 --- a/src/nvim/lua/api_wrappers.c +++ b/src/nvim/lua/api_wrappers.c @@ -1,19 +1,19 @@ -#include -#include -#include +#include // IWYU pragma: keep +#include // IWYU pragma: keep +#include // IWYU pragma: keep -#include "nvim/api/private/defs.h" -#include "nvim/api/private/dispatch.h" -#include "nvim/api/private/helpers.h" -#include "nvim/errors.h" -#include "nvim/ex_docmd.h" -#include "nvim/ex_getln.h" -#include "nvim/func_attr.h" -#include "nvim/globals.h" -#include "nvim/lua/converter.h" -#include "nvim/lua/executor.h" -#include "nvim/memory.h" +#include "nvim/api/private/defs.h" // IWYU pragma: keep +#include "nvim/api/private/dispatch.h" // IWYU pragma: keep +#include "nvim/api/private/helpers.h" // IWYU pragma: keep +#include "nvim/errors.h" // IWYU pragma: keep +#include "nvim/ex_docmd.h" // IWYU pragma: keep +#include "nvim/ex_getln.h" // IWYU pragma: keep +#include "nvim/func_attr.h" // IWYU pragma: keep +#include "nvim/globals.h" // IWYU pragma: keep +#include "nvim/lua/converter.h" // IWYU pragma: keep +#include "nvim/lua/executor.h" // IWYU pragma: keep +#include "nvim/memory.h" // IWYU pragma: keep #ifdef INCLUDE_GENERATED_DECLARATIONS -# include "lua_api_c_bindings.generated.h" +# include "lua_api_c_bindings.generated.h" // IWYU pragma: keep #endif diff --git a/src/nvim/lua/converter.c b/src/nvim/lua/converter.c index 45ead154bc..292588ee64 100644 --- a/src/nvim/lua/converter.c +++ b/src/nvim/lua/converter.c @@ -22,6 +22,7 @@ #include "nvim/lua/executor.h" #include "nvim/macros_defs.h" #include "nvim/memory.h" +#include "nvim/memory_defs.h" #include "nvim/message.h" #include "nvim/types_defs.h" #include "nvim/vim_defs.h" diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index c4fa8b0fff..0a412b4ca9 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -23,7 +23,6 @@ #include "nvim/cursor.h" #include "nvim/drawscreen.h" #include "nvim/errors.h" -#include "nvim/eval.h" #include "nvim/eval/funcs.h" #include "nvim/eval/typval.h" #include "nvim/eval/typval_defs.h" @@ -47,10 +46,12 @@ #include "nvim/lua/treesitter.h" #include "nvim/macros_defs.h" #include "nvim/main.h" +#include "nvim/mbyte_defs.h" #include "nvim/memline.h" #include "nvim/memory.h" #include "nvim/memory_defs.h" #include "nvim/message.h" +#include "nvim/message_defs.h" #include "nvim/msgpack_rpc/channel.h" #include "nvim/option_vars.h" #include "nvim/os/fileio.h" diff --git a/src/nvim/lua/executor.h b/src/nvim/lua/executor.h index 32fde3853b..3a0c03412f 100644 --- a/src/nvim/lua/executor.h +++ b/src/nvim/lua/executor.h @@ -4,10 +4,10 @@ #include #include +#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/cmdexpand_defs.h" // IWYU pragma: keep #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep -#include "nvim/func_attr.h" #include "nvim/macros_defs.h" #include "nvim/types_defs.h" #include "nvim/usercmd.h" // IWYU pragma: keep diff --git a/src/nvim/lua/secure.c b/src/nvim/lua/secure.c index 61277949c4..1560881b55 100644 --- a/src/nvim/lua/secure.c +++ b/src/nvim/lua/secure.c @@ -2,11 +2,11 @@ #include #include +#include "nvim/ascii_defs.h" #include "nvim/charset.h" #include "nvim/errors.h" #include "nvim/ex_cmds_defs.h" #include "nvim/gettext_defs.h" -#include "nvim/globals.h" #include "nvim/lua/executor.h" #include "nvim/lua/secure.h" #include "nvim/memory.h" diff --git a/src/nvim/lua/spell.c b/src/nvim/lua/spell.c index f4dacd7a55..eec5892307 100644 --- a/src/nvim/lua/spell.c +++ b/src/nvim/lua/spell.c @@ -16,7 +16,7 @@ #include "nvim/spell.h" #ifdef INCLUDE_GENERATED_DECLARATIONS -# include "lua/spell.c.generated.h" +# include "lua/spell.c.generated.h" // IWYU pragma: keep #endif int nlua_spell_check(lua_State *lstate) diff --git a/src/nvim/lua/stdlib.c b/src/nvim/lua/stdlib.c index 4de25f4265..2fc9367ead 100644 --- a/src/nvim/lua/stdlib.c +++ b/src/nvim/lua/stdlib.c @@ -18,11 +18,13 @@ #include "nvim/api/private/helpers.h" #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" +#include "nvim/autocmd_defs.h" #include "nvim/buffer_defs.h" #include "nvim/eval/typval.h" #include "nvim/eval/typval_defs.h" #include "nvim/eval/vars.h" #include "nvim/eval/window.h" +#include "nvim/ex_cmds_defs.h" #include "nvim/ex_docmd.h" #include "nvim/ex_eval.h" #include "nvim/fold.h" diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c index c80e7b7672..3e5d3e24fe 100644 --- a/src/nvim/lua/treesitter.c +++ b/src/nvim/lua/treesitter.c @@ -19,8 +19,8 @@ # include #endif -#include "klib/kvec.h" #include "nvim/api/private/helpers.h" +#include "nvim/ascii_defs.h" #include "nvim/buffer_defs.h" #include "nvim/globals.h" #include "nvim/lua/treesitter.h" @@ -28,7 +28,6 @@ #include "nvim/map_defs.h" #include "nvim/memline.h" #include "nvim/memory.h" -#include "nvim/os/fs.h" #include "nvim/pos_defs.h" #include "nvim/strings.h" #include "nvim/types_defs.h" diff --git a/src/nvim/lua/xdiff.c b/src/nvim/lua/xdiff.c index b9f96abf73..f51c1a05cd 100644 --- a/src/nvim/lua/xdiff.c +++ b/src/nvim/lua/xdiff.c @@ -1,4 +1,5 @@ #include +#include #include #include #include -- cgit From 25abcd243e413f960a7a58a44689e8bfbbc3dec7 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 23 Dec 2024 15:14:40 +0100 Subject: fix: fix broken wasmtime build Regression from 2a7d0ed6145bf3f8b139c2694563f460f829813a, which removed header that is only needed if wasmtime support is enabled. Prevent this from happening again by wrapping the include in a `HAVE_WASMTIME` check. --- src/nvim/lua/treesitter.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/nvim/lua') diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c index 3e5d3e24fe..28ad2cf4d3 100644 --- a/src/nvim/lua/treesitter.c +++ b/src/nvim/lua/treesitter.c @@ -17,6 +17,8 @@ #ifdef HAVE_WASMTIME # include + +# include "nvim/os/fs.h" #endif #include "nvim/api/private/helpers.h" -- cgit From ead5683ff9994c0fbfc6c38e0911d9455777550b Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Tue, 7 Jan 2025 14:20:45 +0100 Subject: feat(api): add err field to nvim_echo() opts Problem: We want to deprecate `nvim_err_write(ln)()` but there is no obvious replacement (from Lua). Meanwhile we already have `nvim_echo()` with an `opts` argument. Solution: Add `err` argument to `nvim_echo()` that directly maps to `:echoerr`. --- src/nvim/lua/executor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/lua') diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index 0a412b4ca9..68d3af6074 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -958,7 +958,7 @@ static void nlua_print_event(void **argv) HlMessage msg = KV_INITIAL_VALUE; HlMessageChunk chunk = { { .data = argv[0], .size = (size_t)(intptr_t)argv[1] - 1 }, 0 }; kv_push(msg, chunk); - msg_multihl(msg, "lua_print", true); + msg_multihl(msg, "lua_print", true, false); } /// Print as a Vim message -- cgit From 45e606b1fddbfeee8fe28385b5371ca6f2fba71b Mon Sep 17 00:00:00 2001 From: Riley Bruins Date: Wed, 18 Dec 2024 10:48:33 -0800 Subject: feat(treesitter): async parsing **Problem:** Parsing can be slow for large files, and it is a blocking operation which can be disruptive and annoying. **Solution:** Provide a function for asynchronous parsing, which accepts a callback to be run after parsing completes. Co-authored-by: Lewis Russell Co-authored-by: Luuk van Baal Co-authored-by: VanaIgr --- src/nvim/lua/treesitter.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/nvim/lua') diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c index 28ad2cf4d3..9bd2baad27 100644 --- a/src/nvim/lua/treesitter.c +++ b/src/nvim/lua/treesitter.c @@ -489,7 +489,11 @@ static int parser_parse(lua_State *L) // Sometimes parsing fails (timeout, or wrong parser ABI) // In those case, just return an error. if (!new_tree) { - return luaL_error(L, "An error occurred when parsing."); + if (ts_parser_timeout_micros(p) == 0) { + // No timeout set, must have had an error + return luaL_error(L, "An error occurred when parsing."); + } + return 0; } // The new tree will be pushed to the stack, without copy, ownership is now to the lua GC. -- cgit From 5a54681025ec28129c21c875943a3f9c37959f75 Mon Sep 17 00:00:00 2001 From: Horror Proton <107091537+horror-proton@users.noreply.github.com> Date: Tue, 14 Jan 2025 00:43:33 +0800 Subject: fix(treesitter): uv_dlclose after uv_dlerror --- src/nvim/lua/treesitter.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/nvim/lua') diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c index 9bd2baad27..3493384a8f 100644 --- a/src/nvim/lua/treesitter.c +++ b/src/nvim/lua/treesitter.c @@ -128,9 +128,9 @@ static const TSLanguage *load_language_from_object(lua_State *L, const char *pat { uv_lib_t lib; if (uv_dlopen(path, &lib)) { + xstrlcpy(IObuff, uv_dlerror(&lib), sizeof(IObuff)); uv_dlclose(&lib); - luaL_error(L, "Failed to load parser for language '%s': uv_dlopen: %s", - lang_name, uv_dlerror(&lib)); + luaL_error(L, "Failed to load parser for language '%s': uv_dlopen: %s", lang_name, IObuff); } char symbol_buf[128]; @@ -138,8 +138,9 @@ static const TSLanguage *load_language_from_object(lua_State *L, const char *pat TSLanguage *(*lang_parser)(void); if (uv_dlsym(&lib, symbol_buf, (void **)&lang_parser)) { + xstrlcpy(IObuff, uv_dlerror(&lib), sizeof(IObuff)); uv_dlclose(&lib); - luaL_error(L, "Failed to load parser: uv_dlsym: %s", uv_dlerror(&lib)); + luaL_error(L, "Failed to load parser: uv_dlsym: %s", IObuff); } TSLanguage *lang = lang_parser(); -- cgit From a5b1b83a2693ffa7a5a0a22b3693d36ea60051be Mon Sep 17 00:00:00 2001 From: "林玮 (Jade Lin)" Date: Sat, 18 Jan 2025 16:40:40 +0800 Subject: fix(lua): prevent SIGSEGV when lua error is NULL in libuv_worker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- src/nvim/lua/executor.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/nvim/lua') 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))); -- cgit From c6d2cbf8f51abfa0c9d244ef384a15b0b69e16c6 Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Thu, 23 Jan 2025 12:42:38 +0100 Subject: fix(lua): pop retval for fast context LuaRef Problem: nlua_call_ref_ctx() does not pop the return value in fast context that did not error. Solution: Fall through to end; calling nlua_call_pop_retval(). --- src/nvim/lua/executor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/lua') diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index a5b48a5d5e..71c5cd4585 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -1587,8 +1587,8 @@ Object nlua_call_ref_ctx(bool fast, LuaRef ref, const char *name, Array args, Lu if (nlua_fast_cfpcall(lstate, nargs, 1, -1) < 0) { // error is already scheduled, set anyways to convey failure. api_set_error(err, kErrorTypeException, "fast context failure"); + return NIL; } - return NIL; } else if (nlua_pcall(lstate, nargs, 1)) { // if err is passed, the caller will deal with the error. if (err) { -- cgit From eb60cd74fb5caa997e6253bef6a1f0b58e1b6ec6 Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Mon, 27 Jan 2025 16:16:06 +0100 Subject: build(deps)!: bump tree-sitter to HEAD, wasmtime to v29.0.1 (#32200) Breaking change: `ts_node_child_containing_descendant()` was removed Breaking change: tree-sitter 0.25 (HEAD) required --- src/nvim/lua/treesitter.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) (limited to 'src/nvim/lua') diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c index 3493384a8f..c7999ac077 100644 --- a/src/nvim/lua/treesitter.c +++ b/src/nvim/lua/treesitter.c @@ -218,7 +218,7 @@ static int add_language(lua_State *L, bool is_wasm) ? load_language_from_wasm(L, path, lang_name) : load_language_from_object(L, path, lang_name, symbol_name); - uint32_t lang_version = ts_language_version(lang); + uint32_t lang_version = ts_language_abi_version(lang); if (lang_version < TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION || lang_version > TREE_SITTER_LANGUAGE_VERSION) { return luaL_error(L, @@ -300,7 +300,7 @@ int tslua_inspect_lang(lua_State *L) lua_pushboolean(L, ts_language_is_wasm(lang)); lua_setfield(L, -2, "_wasm"); - lua_pushinteger(L, ts_language_version(lang)); // [retval, version] + lua_pushinteger(L, ts_language_abi_version(lang)); // [retval, version] lua_setfield(L, -2, "_abi_version"); return 1; @@ -476,7 +476,7 @@ static int parser_parse(lua_State *L) #undef BUFSIZE } - input = (TSInput){ (void *)buf, input_cb, TSInputEncodingUTF8 }; + input = (TSInput){ (void *)buf, input_cb, TSInputEncodingUTF8, NULL }; new_tree = ts_parser_parse(p, old_tree, input); break; @@ -837,7 +837,6 @@ static struct luaL_Reg node_meta[] = { { "named_descendant_for_range", node_named_descendant_for_range }, { "parent", node_parent }, { "__has_ancestor", __has_ancestor }, - { "child_containing_descendant", node_child_containing_descendant }, { "child_with_descendant", node_child_with_descendant }, { "iter_children", node_iter_children }, { "next_sibling", node_next_sibling }, @@ -1181,15 +1180,6 @@ static int __has_ancestor(lua_State *L) return 1; } -static int node_child_containing_descendant(lua_State *L) -{ - TSNode node = node_check(L, 1); - TSNode descendant = node_check(L, 2); - TSNode child = ts_node_child_containing_descendant(node, descendant); - push_node(L, child, 1); - return 1; -} - static int node_child_with_descendant(lua_State *L) { TSNode node = node_check(L, 1); -- cgit From 77be44563acb64a481d48f45c8dbbfca2d7db415 Mon Sep 17 00:00:00 2001 From: Riley Bruins Date: Sun, 2 Feb 2025 03:46:26 -0800 Subject: refactor(treesitter): always return valid range from parse() #32273 Problem: When running an initial parse, parse() returns an empty table rather than an actual range. In `languagetree.lua`, we manually check if a parse was incremental to determine the changed parse region. Solution: - Always return a range (in the C side) from parse(). - Simplify the language tree code a bit. - Logger no longer shows empty ranges on the initial parse. --- src/nvim/lua/treesitter.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/nvim/lua') diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c index c7999ac077..3e33fcd142 100644 --- a/src/nvim/lua/treesitter.c +++ b/src/nvim/lua/treesitter.c @@ -500,7 +500,8 @@ static int parser_parse(lua_State *L) // The new tree will be pushed to the stack, without copy, ownership is now to the lua GC. // Old tree is owned by lua GC since before uint32_t n_ranges = 0; - TSRange *changed = old_tree ? ts_tree_get_changed_ranges(old_tree, new_tree, &n_ranges) : NULL; + TSRange *changed = old_tree ? ts_tree_get_changed_ranges(old_tree, new_tree, &n_ranges) + : ts_tree_included_ranges(new_tree, &n_ranges); push_tree(L, new_tree); // [tree] -- cgit