Skip to content

Commit ccd42e6

Browse files
committed
add load_from_std_lib function to Lua state
This function allows loading of any portion of the standard libraries after initial state creation. Specifically, this is filling a need to load the debug library after an error is encountered so that a traceback can be generated without risking exposing the debug library anywhere else in the code.
1 parent eda13ab commit ccd42e6

File tree

1 file changed

+57
-41
lines changed

1 file changed

+57
-41
lines changed

src/lua.rs

Lines changed: 57 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,18 @@ impl Lua {
125125
create_lua(lua_mod)
126126
}
127127

128+
/// Loads standard the specified set of the standard libraries into an existing Lua state.
129+
///
130+
/// Use the [`StdLib`] flags to specifiy the libraries you want to load.
131+
///
132+
/// This function is unsafe because it can be used to load the `debug` library which can be used
133+
/// to break the safety guarantees provided by rlua.
134+
pub unsafe fn load_from_std_lib(&self, lua_mod: StdLib) -> Result<()> {
135+
protect_lua_closure(self.main_state, 0, 0, |state| {
136+
load_from_std_lib(state, lua_mod);
137+
})
138+
}
139+
128140
/// The main entry point of the rlua API.
129141
///
130142
/// In order to create Lua values, load and execute Lua code, or otherwise interact with the Lua
@@ -414,47 +426,7 @@ unsafe fn create_lua(lua_mod_to_load: StdLib) -> Lua {
414426

415427
extra.ref_thread = rlua_expect!(
416428
protect_lua_closure(state, 0, 0, |state| {
417-
// Do not open the debug library, it can be used to cause unsafety.
418-
if lua_mod_to_load.contains(StdLib::BASE) {
419-
ffi::luaL_requiref(state, cstr!("_G"), ffi::luaopen_base, 1);
420-
ffi::lua_pop(state, 1);
421-
}
422-
if lua_mod_to_load.contains(StdLib::COROUTINE) {
423-
ffi::luaL_requiref(state, cstr!("coroutine"), ffi::luaopen_coroutine, 1);
424-
ffi::lua_pop(state, 1);
425-
}
426-
if lua_mod_to_load.contains(StdLib::TABLE) {
427-
ffi::luaL_requiref(state, cstr!("table"), ffi::luaopen_table, 1);
428-
ffi::lua_pop(state, 1);
429-
}
430-
if lua_mod_to_load.contains(StdLib::IO) {
431-
ffi::luaL_requiref(state, cstr!("io"), ffi::luaopen_io, 1);
432-
ffi::lua_pop(state, 1);
433-
}
434-
if lua_mod_to_load.contains(StdLib::OS) {
435-
ffi::luaL_requiref(state, cstr!("os"), ffi::luaopen_os, 1);
436-
ffi::lua_pop(state, 1);
437-
}
438-
if lua_mod_to_load.contains(StdLib::STRING) {
439-
ffi::luaL_requiref(state, cstr!("string"), ffi::luaopen_string, 1);
440-
ffi::lua_pop(state, 1);
441-
}
442-
if lua_mod_to_load.contains(StdLib::UTF8) {
443-
ffi::luaL_requiref(state, cstr!("utf8"), ffi::luaopen_utf8, 1);
444-
ffi::lua_pop(state, 1);
445-
}
446-
if lua_mod_to_load.contains(StdLib::MATH) {
447-
ffi::luaL_requiref(state, cstr!("math"), ffi::luaopen_math, 1);
448-
ffi::lua_pop(state, 1);
449-
}
450-
if lua_mod_to_load.contains(StdLib::PACKAGE) {
451-
ffi::luaL_requiref(state, cstr!("package"), ffi::luaopen_package, 1);
452-
ffi::lua_pop(state, 1);
453-
}
454-
if lua_mod_to_load.contains(StdLib::DEBUG) {
455-
ffi::luaL_requiref(state, cstr!("debug"), ffi::luaopen_debug, 1);
456-
ffi::lua_pop(state, 1);
457-
}
429+
load_from_std_lib(state, lua_mod_to_load);
458430

459431
init_error_registry(state);
460432

@@ -513,4 +485,48 @@ unsafe fn create_lua(lua_mod_to_load: StdLib) -> Lua {
513485
}
514486
}
515487

488+
unsafe fn load_from_std_lib(state: *mut ffi::lua_State, lua_mod: StdLib) {
489+
// Do not open the debug library, it can be used to cause unsafety.
490+
if lua_mod.contains(StdLib::BASE) {
491+
ffi::luaL_requiref(state, cstr!("_G"), ffi::luaopen_base, 1);
492+
ffi::lua_pop(state, 1);
493+
}
494+
if lua_mod.contains(StdLib::COROUTINE) {
495+
ffi::luaL_requiref(state, cstr!("coroutine"), ffi::luaopen_coroutine, 1);
496+
ffi::lua_pop(state, 1);
497+
}
498+
if lua_mod.contains(StdLib::TABLE) {
499+
ffi::luaL_requiref(state, cstr!("table"), ffi::luaopen_table, 1);
500+
ffi::lua_pop(state, 1);
501+
}
502+
if lua_mod.contains(StdLib::IO) {
503+
ffi::luaL_requiref(state, cstr!("io"), ffi::luaopen_io, 1);
504+
ffi::lua_pop(state, 1);
505+
}
506+
if lua_mod.contains(StdLib::OS) {
507+
ffi::luaL_requiref(state, cstr!("os"), ffi::luaopen_os, 1);
508+
ffi::lua_pop(state, 1);
509+
}
510+
if lua_mod.contains(StdLib::STRING) {
511+
ffi::luaL_requiref(state, cstr!("string"), ffi::luaopen_string, 1);
512+
ffi::lua_pop(state, 1);
513+
}
514+
if lua_mod.contains(StdLib::UTF8) {
515+
ffi::luaL_requiref(state, cstr!("utf8"), ffi::luaopen_utf8, 1);
516+
ffi::lua_pop(state, 1);
517+
}
518+
if lua_mod.contains(StdLib::MATH) {
519+
ffi::luaL_requiref(state, cstr!("math"), ffi::luaopen_math, 1);
520+
ffi::lua_pop(state, 1);
521+
}
522+
if lua_mod.contains(StdLib::PACKAGE) {
523+
ffi::luaL_requiref(state, cstr!("package"), ffi::luaopen_package, 1);
524+
ffi::lua_pop(state, 1);
525+
}
526+
if lua_mod.contains(StdLib::DEBUG) {
527+
ffi::luaL_requiref(state, cstr!("debug"), ffi::luaopen_debug, 1);
528+
ffi::lua_pop(state, 1);
529+
}
530+
}
531+
516532
pub(crate) static FUNCTION_METATABLE_REGISTRY_KEY: u8 = 0;

0 commit comments

Comments
 (0)