fix(eluna): Fix GC re-entrancy crash in CollectGarbage

The CollectGarbage metamethod was calling Eluna::GetEluna(L) which uses
lua_pushstring internally. This can trigger another GC cycle while already
inside the GC handler, causing memory corruption and crashes.

The fix avoids GetEluna entirely by directly casting the userdata to
ElunaObject without type checking, which is safe since the __gc metamethod
is only called on valid userdata of the correct type.

This fixes crashes in SHOW_WAYPOINTS and other handlers that hold creature
references when GC runs during method calls.
This commit is contained in:
2025-12-13 19:18:06 -05:00
parent fad074ef41
commit 5c8da59fe8

View File

@@ -480,12 +480,17 @@ public:
// Remember special cases like ElunaTemplate<Vehicle>::CollectGarbage
static int CollectGarbage(lua_State* L)
{
Eluna* E = Eluna::GetEluna(L);
// Get object pointer (and check type, no error)
ElunaObject* obj = E->CHECKOBJ<ElunaObject>(1, false);
if (obj)
// IMPORTANT: Do NOT call Eluna::GetEluna(L) here!
// GetEluna uses lua_pushstring which can trigger GC re-entrancy,
// causing memory corruption when we're already inside the GC handler.
// Instead, get the userdata directly without type checking.
void* ud = lua_touserdata(L, 1);
if (ud)
{
ElunaObject* obj = static_cast<ElunaObject*>(ud);
obj->~ElunaObject();
}
return 0;
}