From 5508db9a20d995804edccd48144292ab1b8d8b08 Mon Sep 17 00:00:00 2001 From: Aurelien DARRAGON Date: Fri, 1 Mar 2024 19:54:16 +0100 Subject: [PATCH] BUG/MINOR: hlua: fix unsafe lua_tostring() usage with empty stack Lua documentation says that lua_tostring() returns a pointer that remains valid as long as the object is not removed from the stack. However there are some places were we use the returned string AFTER the corresponding object is removed from the stack. In practise this doesn't seem to cause visible bugs (probably because the pointer remains valid waiting for a GC cycle), but let's fix that to comply with the documentation and avoid undefined behavior. It should be backported in all stable versions. --- src/hlua.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/hlua.c b/src/hlua.c index d915b10874..d8dcbf260a 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -1821,12 +1821,15 @@ resume_execution: break; } msg = lua_tostring(lua->T, -1); - lua_settop(lua->T, 0); /* Empty the stack. */ trace = hlua_traceback(lua->T, ", "); if (msg) lua_pushfstring(lua->T, "[state-id %d] runtime error: %s from %s", lua->state_id, msg, trace); else lua_pushfstring(lua->T, "[state-id %d] unknown runtime error from %s", lua->state_id, trace); + + /* Move the error msg at the top and then empty the stack except last msg */ + lua_insert(lua->T, -lua_gettop(lua->T)); + lua_settop(lua->T, 1); ret = HLUA_E_ERRMSG; break; @@ -1843,11 +1846,14 @@ resume_execution: break; } msg = lua_tostring(lua->T, -1); - lua_settop(lua->T, 0); /* Empty the stack. */ if (msg) lua_pushfstring(lua->T, "[state-id %d] message handler error: %s", lua->state_id, msg); else lua_pushfstring(lua->T, "[state-id %d] message handler error", lua->state_id); + + /* Move the error msg at the top and then empty the stack except last msg */ + lua_insert(lua->T, -lua_gettop(lua->T)); + lua_settop(lua->T, 1); ret = HLUA_E_ERRMSG; break; @@ -13039,12 +13045,13 @@ int hlua_post_init_state(lua_State *L) if (!kind) kind = "runtime error"; msg = lua_tostring(L, -1); - lua_settop(L, 0); /* Empty the stack. */ trace = hlua_traceback(L, ", "); if (msg) ha_alert("Lua init: %s: '%s' from %s\n", kind, msg, trace); else ha_alert("Lua init: unknown %s from %s\n", kind, trace); + + lua_settop(L, 0); /* Empty the stack. */ return_status = 0; break; -- 2.39.5