mirror of
https://github.com/neovim/neovim.git
synced 2026-05-26 06:48:27 +00:00
fix(treesitter): crash in ts_parser_delete after gc #39497
Problem: parser_gc() calls ts_parser_delete() but leaves the userdata pointer pointing to freed memory. If the GC finalizer runs at an unexpected time (e.g. inside nvim_buf_get_lines #39411), a stale pointer could cause a crash. Solution: - NULL out `*ud` after ts_parser_delete() in parser_gc() - Update parser_check() to handle NULL with a clear error message, guarding all parser methods against UAF Co-authored-by: Lewis Russell <lewis6991@gmail.com> Signed-off-by: Szymon Wilczek <swilczek.lx@gmail.com>
This commit is contained in:
@@ -399,10 +399,10 @@ static int tslua_push_parser(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static TSParser *parser_check(lua_State *L, uint16_t index)
|
||||
static TSParser *parser_check(lua_State *L, int index)
|
||||
{
|
||||
TSParser **ud = luaL_checkudata(L, index, TS_META_PARSER);
|
||||
luaL_argcheck(L, *ud, index, "TSParser expected");
|
||||
luaL_argcheck(L, *ud != NULL, index, "Parser has been deleted");
|
||||
return *ud;
|
||||
}
|
||||
|
||||
@@ -419,9 +419,12 @@ static void logger_gc(TSLogger logger)
|
||||
|
||||
static int parser_gc(lua_State *L)
|
||||
{
|
||||
TSParser *p = parser_check(L, 1);
|
||||
logger_gc(ts_parser_logger(p));
|
||||
ts_parser_delete(p);
|
||||
TSParser **ud = luaL_checkudata(L, 1, TS_META_PARSER);
|
||||
if (*ud) {
|
||||
logger_gc(ts_parser_logger(*ud));
|
||||
ts_parser_delete(*ud);
|
||||
*ud = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user