From 5aa8723120f3421599a9af4edbf91f9364bcfea7 Mon Sep 17 00:00:00 2001 From: Lucy Date: Sat, 26 Oct 2024 05:43:30 -0400 Subject: [PATCH] Add isolated lua states --- src/lib.rs | 5 +++-- src/state/library/global.rs | 15 ++++++++++----- src/state/mod.rs | 12 +++++++++++- src/value/conversion/into.rs | 8 +++++++- 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index bb8bc03..2b2d6c7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,8 +8,9 @@ pub(crate) mod wrappers; pub use state::{ awaken, call_function, clear_execution_limit, clear_ref_userdata, collect_garbage, get_globals, - get_traceback, kill_sleeping_thread, kill_state, kill_yielded_thread, list_threads, load, - new_state, resume, set_execution_limit_millis, set_execution_limit_secs, set_usr, + get_traceback, is_isolated, kill_sleeping_thread, kill_state, kill_yielded_thread, + list_threads, load, new_state, resume, set_execution_limit_millis, set_execution_limit_secs, + set_usr, }; pub use wrappers::{ diff --git a/src/state/library/global.rs b/src/state/library/global.rs index 7b6d2e7..f9dc228 100644 --- a/src/state/library/global.rs +++ b/src/state/library/global.rs @@ -18,9 +18,8 @@ impl LuaModule for GlobalModule { fn create_items<'lua>(&self, lua: &'lua Lua) -> LuaResult)>> { let id = self.0; let id1 = self.0; - Ok(vec![ - ("dm", (&DmModule as &dyn LuaModule).into_lua(lua)?), - ("list", (&ListModule as &dyn LuaModule).into_lua(lua)?), + let isolate = lua.named_registry_value::("isolated")?; + let mut items = vec![ ( "loadstring", Function::wrap(|lua, code: String| { @@ -29,7 +28,6 @@ impl LuaModule for GlobalModule { }) .into_lua(lua)?, ), - ("pointer", (&PointerModule as &dyn LuaModule).into_lua(lua)?), ( "sleep", unsafe { lua.create_c_function(sleep) }.map(LuaValue::Function)?, @@ -40,8 +38,15 @@ impl LuaModule for GlobalModule { ), ("_exec", (&ExecModule as &dyn LuaModule).into_lua(lua)?), ("_state_id", LuaValue::Integer(id)), - ]) + ]; + if !isolate { + items.push(("dm", (&DmModule as &dyn LuaModule).into_lua(lua)?)); + items.push(("list", (&ListModule as &dyn LuaModule).into_lua(lua)?)); + items.push(("pointer", (&PointerModule as &dyn LuaModule).into_lua(lua)?)); + } + Ok(items) } + fn create_metamethods<'lua>( &self, _: &'lua Lua, diff --git a/src/state/mod.rs b/src/state/mod.rs index 2fae62e..395e535 100644 --- a/src/state/mod.rs +++ b/src/state/mod.rs @@ -38,8 +38,10 @@ thread_local! { #[map_statics(mut STATES)] #[byond_fn] -pub fn new_state() -> ByondResult { +pub fn new_state(isolate: Option) -> ByondResult { let lua: Lua = Lua::new(); + lua.set_named_registry_value("isolated", isolate.unwrap_or(false)) + .map_err(ByondError::boxed)?; let new_state_index = states.iter().position(Option::is_none).unwrap_or_else(|| { states.push(None); states.len() - 1 @@ -70,6 +72,14 @@ fn get_state(index: usize) -> ByondResult> { ))) } +#[byond_fn] +pub fn is_isolated(index: usize) -> ByondResult { + get_state(index).and_then(|lua| { + lua.named_registry_value("isolated") + .map_err(ByondError::boxed) + }) +} + #[byond_fn] pub fn load(index: usize, code: String, name: Option) -> ByondResult { get_state(index).and_then(|lua| run::load(lua.as_ref(), code, name)) diff --git a/src/value/conversion/into.rs b/src/value/conversion/into.rs index ef5f818..5c7d3ea 100644 --- a/src/value/conversion/into.rs +++ b/src/value/conversion/into.rs @@ -82,6 +82,12 @@ impl<'lua> IntoLua<'lua> for Value { .into_printed_external()? .into_lua(lua); }; - get_or_create_cached_userdata(self, lua)?.into_lua(lua) + // If isolated, never allow any sort of userdata to be exposed. + let isolate = lua.named_registry_value::("isolated")?; + if isolate { + Ok(LuaValue::Nil) + } else { + get_or_create_cached_userdata(self, lua)?.into_lua(lua) + } } }