From 6bb7f099273c8d97d7bae8afcc78e8d5fea4464a Mon Sep 17 00:00:00 2001 From: Alex Orlenko Date: Tue, 27 Jan 2026 14:07:47 +0000 Subject: [PATCH] Don't use `luaL_typename` to get a static type name in Luau. In Luau this function returns heap-allocated string rather than static string, so accessing this value when Lua state is destroyed is UB. Fixes #674 --- src/conversion.rs | 3 ++- src/state/raw.rs | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/conversion.rs b/src/conversion.rs index b02e861..9ae5ce6 100644 --- a/src/conversion.rs +++ b/src/conversion.rs @@ -1211,7 +1211,8 @@ impl FromLua for Either { Err(_) => match R::from_stack(idx, lua).map(Either::Right) { Ok(r) => Ok(r), Err(_) => { - let value_type_name = CStr::from_ptr(ffi::luaL_typename(lua.state(), idx)); + let value_type_name = + CStr::from_ptr(ffi::lua_typename(lua.state(), ffi::lua_type(lua.state(), idx))); Err(Error::FromLuaConversionError { from: value_type_name.to_str().unwrap(), to: Self::type_name(), diff --git a/src/state/raw.rs b/src/state/raw.rs index 8ab2d6e..13ce9d8 100644 --- a/src/state/raw.rs +++ b/src/state/raw.rs @@ -1219,7 +1219,10 @@ impl RawLua { Ok(type_id) => Ok(type_id), Err(Error::UserDataTypeMismatch) if ffi::lua_type(state, idx) != ffi::LUA_TUSERDATA => { // Report `FromLuaConversionError` instead - let idx_type_name = CStr::from_ptr(ffi::luaL_typename(state, idx)); + // In Luau `luaL_typename` return heap-allocated string that is valid only for + // the `state` lifetime. + // `lua_typename` is used instead to get a truly static string. + let idx_type_name = CStr::from_ptr(ffi::lua_typename(state, ffi::lua_type(state, idx))); let idx_type_name = idx_type_name.to_str().unwrap(); let message = format!("expected userdata of type '{}'", short_type_name::()); Err(Error::from_lua_conversion(idx_type_name, "userdata", message))