Add more checks for destructed userdata in AnyUserData

This commit is contained in:
Alex Orlenko 2021-04-11 00:07:04 +01:00
parent c10169a380
commit 41a1a0d15a
3 changed files with 28 additions and 12 deletions

View File

@ -25,10 +25,10 @@ use crate::userdata::{
AnyUserData, MetaMethod, UserData, UserDataFields, UserDataMethods, UserDataWrapped, AnyUserData, MetaMethod, UserData, UserDataFields, UserDataMethods, UserDataWrapped,
}; };
use crate::util::{ use crate::util::{
assert_stack, callback_error, check_stack, get_gc_userdata, get_main_state, get_userdata, assert_stack, callback_error, check_stack, get_destructed_userdata_metatable, get_gc_userdata,
get_wrapped_error, init_error_registry, init_gc_metatable_for, init_userdata_metatable, get_main_state, get_userdata, get_wrapped_error, init_error_registry, init_gc_metatable_for,
pop_error, push_gc_userdata, push_userdata, push_wrapped_error, StackGuard, WrappedError, init_userdata_metatable, pop_error, push_gc_userdata, push_userdata, push_wrapped_error,
WrappedPanic, StackGuard, WrappedError, WrappedPanic,
}; };
use crate::value::{FromLua, FromLuaMulti, MultiValue, Nil, ToLua, ToLuaMulti, Value}; use crate::value::{FromLua, FromLuaMulti, MultiValue, Nil, ToLua, ToLuaMulti, Value};
@ -44,7 +44,7 @@ use {
}; };
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
use {crate::util::get_destructed_userdata_metatable, serde::Serialize}; use serde::Serialize;
/// Top level Lua struct which holds the Lua state itself. /// Top level Lua struct which holds the Lua state itself.
pub struct Lua { pub struct Lua {
@ -1588,7 +1588,6 @@ impl Lua {
// Pushes a LuaRef value onto the stack, checking that it's a registered // Pushes a LuaRef value onto the stack, checking that it's a registered
// and not destructed UserData. // and not destructed UserData.
// Uses 3 stack spaces, does not call checkstack // Uses 3 stack spaces, does not call checkstack
#[cfg(feature = "serialize")]
pub(crate) unsafe fn push_userdata_ref(&self, lref: &LuaRef) -> Result<()> { pub(crate) unsafe fn push_userdata_ref(&self, lref: &LuaRef) -> Result<()> {
self.push_ref(lref); self.push_ref(lref);
if ffi::lua_getmetatable(self.state, -1) == 0 { if ffi::lua_getmetatable(self.state, -1) == 0 {

View File

@ -685,8 +685,8 @@ impl<'lua> AnyUserData<'lua> {
let v = v.to_lua(lua)?; let v = v.to_lua(lua)?;
unsafe { unsafe {
let _sg = StackGuard::new(lua.state); let _sg = StackGuard::new(lua.state);
assert_stack(lua.state, 2); assert_stack(lua.state, 3);
lua.push_ref(&self.0); lua.push_userdata_ref(&self.0)?;
lua.push_value(v)?; lua.push_value(v)?;
ffi::lua_setuservalue(lua.state, -2); ffi::lua_setuservalue(lua.state, -2);
Ok(()) Ok(())
@ -702,8 +702,8 @@ impl<'lua> AnyUserData<'lua> {
let lua = self.0.lua; let lua = self.0.lua;
let res = unsafe { let res = unsafe {
let _sg = StackGuard::new(lua.state); let _sg = StackGuard::new(lua.state);
assert_stack(lua.state, 2); assert_stack(lua.state, 3);
lua.push_ref(&self.0); lua.push_userdata_ref(&self.0)?;
ffi::lua_getuservalue(lua.state, -1); ffi::lua_getuservalue(lua.state, -1);
lua.pop_value() lua.pop_value()
}; };
@ -754,9 +754,9 @@ impl<'lua> AnyUserData<'lua> {
unsafe { unsafe {
let lua = self.0.lua; let lua = self.0.lua;
let _sg = StackGuard::new(lua.state); let _sg = StackGuard::new(lua.state);
assert_stack(lua.state, 2); assert_stack(lua.state, 3);
lua.push_ref(&self.0); lua.push_userdata_ref(&self.0)?;
if ffi::lua_getmetatable(lua.state, -1) == 0 { if ffi::lua_getmetatable(lua.state, -1) == 0 {
return Err(Error::UserDataTypeMismatch); return Err(Error::UserDataTypeMismatch);
} }

View File

@ -286,6 +286,15 @@ fn scope_userdata_drop() -> Result<()> {
Err(err) => panic!("improper borrow error for destructed userdata: {:?}", err), Err(err) => panic!("improper borrow error for destructed userdata: {:?}", err),
} }
match ud.get_metatable() {
Ok(_) => panic!("successful metatable retrieval of destructed userdata"),
Err(Error::UserDataDestructed) => {}
Err(err) => panic!(
"improper metatable error for destructed userdata: {:?}",
err
),
}
Ok(()) Ok(())
} }
@ -336,6 +345,14 @@ fn scope_nonstatic_userdata_drop() -> Result<()> {
Err(Error::UserDataDestructed) => {} Err(Error::UserDataDestructed) => {}
Err(err) => panic!("improper borrow error for destructed userdata: {:?}", err), Err(err) => panic!("improper borrow error for destructed userdata: {:?}", err),
} }
match ud.get_metatable() {
Ok(_) => panic!("successful metatable retrieval of destructed userdata"),
Err(Error::UserDataDestructed) => {}
Err(err) => panic!(
"improper metatable error for destructed userdata: {:?}",
err
),
}
Ok(()) Ok(())
} }