Skip to content

Commit ce8955f

Browse files
committed
Don't try to disable c modules without package loaded. Fix #24
1 parent 368c442 commit ce8955f

File tree

3 files changed

+39
-4
lines changed

3 files changed

+39
-4
lines changed

src/lua.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ struct ExtraData {
6161
registered_userdata_mt: HashSet<isize>,
6262
registry_unref_list: Arc<Mutex<Option<Vec<c_int>>>>,
6363

64+
libs: StdLib,
6465
mem_info: *mut MemoryInfo,
6566

6667
ref_thread: *mut ffi::lua_State,
@@ -172,7 +173,9 @@ impl Lua {
172173

173174
let mut lua = unsafe { Self::unsafe_new_with(libs) };
174175

175-
mlua_expect!(lua.disable_c_modules(), "Error during disabling C modules");
176+
if libs.contains(StdLib::PACKAGE) {
177+
mlua_expect!(lua.disable_c_modules(), "Error during disabling C modules");
178+
}
176179
lua.safe = true;
177180

178181
Ok(lua)
@@ -262,7 +265,7 @@ impl Lua {
262265
lua.ephemeral = false;
263266
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
264267
{
265-
lua.extra.lock().unwrap().mem_info = mem_info;
268+
mlua_expect!(lua.extra.lock(), "extra is poisoned").mem_info = mem_info;
266269
}
267270

268271
mlua_expect!(
@@ -271,6 +274,7 @@ impl Lua {
271274
}),
272275
"Error during loading standard libraries"
273276
);
277+
mlua_expect!(lua.extra.lock(), "extra is poisoned").libs |= libs;
274278

275279
lua
276280
}
@@ -321,6 +325,7 @@ impl Lua {
321325
registered_userdata_mt: HashSet::new(),
322326
registry_unref_list: Arc::new(Mutex::new(Some(Vec::new()))),
323327
ref_thread,
328+
libs: StdLib::NONE,
324329
mem_info: ptr::null_mut(),
325330
// We need 1 extra stack space to move values in and out of the ref stack.
326331
ref_stack_size: ffi::LUA_MINSTACK - 1,
@@ -381,11 +386,20 @@ impl Lua {
381386
}
382387

383388
let state = self.main_state.unwrap_or(self.state);
384-
unsafe {
389+
let res = unsafe {
385390
protect_lua_closure(state, 0, 0, |state| {
386391
load_from_std_lib(state, libs);
387392
})
393+
};
394+
395+
// If `package` library loaded into a safe lua state then disable C modules
396+
let curr_libs = mlua_expect!(self.extra.lock(), "extra is poisoned").libs;
397+
if self.safe && (curr_libs ^ (curr_libs | libs)).contains(StdLib::PACKAGE) {
398+
mlua_expect!(self.disable_c_modules(), "Error during disabling C modules");
388399
}
400+
mlua_expect!(self.extra.lock(), "extra is poisoned").libs |= libs;
401+
402+
res
389403
}
390404

391405
/// Consumes and leaks `Lua` object, returning a static reference `&'static Lua`.
@@ -1655,7 +1669,12 @@ impl Lua {
16551669
'lua: 'callback,
16561670
{
16571671
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
1658-
self.load_from_std_lib(StdLib::COROUTINE)?;
1672+
{
1673+
let libs = mlua_expect!(self.extra.lock(), "extra is poisoned").libs;
1674+
if !libs.contains(StdLib::COROUTINE) {
1675+
self.load_from_std_lib(StdLib::COROUTINE)?;
1676+
}
1677+
}
16591678

16601679
unsafe extern "C" fn call_callback(state: *mut ffi::lua_State) -> c_int {
16611680
callback_error(state, |nargs| {

src/stdlib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ impl StdLib {
4747
/// (unsafe) [`debug`](https://www.lua.org/manual/5.3/manual.html#6.10) library
4848
pub const DEBUG: StdLib = StdLib(1 << 31);
4949

50+
/// No libraries
51+
pub const NONE: StdLib = StdLib(0);
5052
/// (unsafe) All standard libraries
5153
pub const ALL: StdLib = StdLib(u32::MAX);
5254
/// The safe subset of the standard libraries

tests/tests.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,20 @@ fn test_safety() -> Result<()> {
7272
Err(e) => panic!("expected SafetyError, got {:?}", e),
7373
Ok(_) => panic!("expected SafetyError, got no error"),
7474
}
75+
drop(lua);
76+
77+
// Test safety rules after dynamically loading `package` library
78+
let lua = Lua::new_with(StdLib::NONE)?;
79+
assert!(lua.globals().get::<_, Option<Value>>("require")?.is_none());
80+
lua.load_from_std_lib(StdLib::PACKAGE)?;
81+
match lua.load(r#"package.loadlib()"#).exec() {
82+
Err(Error::CallbackError { ref cause, .. }) => match cause.as_ref() {
83+
Error::SafetyError(_) => {}
84+
e => panic!("expected SafetyError cause, got {:?}", e),
85+
},
86+
Err(e) => panic!("expected CallbackError, got {:?}", e),
87+
Ok(_) => panic!("expected CallbackError, got no error"),
88+
};
7589

7690
Ok(())
7791
}

0 commit comments

Comments
 (0)