Skip to content

Commit c1f8abb

Browse files
committed
Do not allow recursive warnings (Lua 5.4)
1 parent d1a587f commit c1f8abb

File tree

3 files changed

+16
-8
lines changed

3 files changed

+16
-8
lines changed

src/state.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -703,18 +703,19 @@ impl Lua {
703703
unsafe extern "C-unwind" fn warn_proc(ud: *mut c_void, msg: *const c_char, tocont: c_int) {
704704
let extra = ud as *mut ExtraData;
705705
callback_error_ext((*extra).raw_lua().state(), extra, |extra, _| {
706-
let cb = mlua_expect!(
707-
(*extra).warn_callback.as_ref(),
708-
"no warning callback set in warn_proc"
709-
);
706+
let warn_callback = (*extra).warn_callback.clone();
707+
let warn_callback = mlua_expect!(warn_callback, "no warning callback set in warn_proc");
708+
if XRc::strong_count(&warn_callback) > 2 {
709+
return Ok(());
710+
}
710711
let msg = StdString::from_utf8_lossy(CStr::from_ptr(msg).to_bytes());
711-
cb((*extra).lua(), &msg, tocont != 0)
712+
warn_callback((*extra).lua(), &msg, tocont != 0)
712713
});
713714
}
714715

715716
let lua = self.lock();
716717
unsafe {
717-
(*lua.extra.get()).warn_callback = Some(Box::new(callback));
718+
(*lua.extra.get()).warn_callback = Some(XRc::new(callback));
718719
ffi::lua_setwarnf(lua.state(), Some(warn_proc), lua.extra.get() as *mut c_void);
719720
}
720721
}

src/types.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,10 @@ pub(crate) type InterruptCallback = XRc<dyn Fn(&Lua) -> Result<VmState> + Send>;
9191
pub(crate) type InterruptCallback = XRc<dyn Fn(&Lua) -> Result<VmState>>;
9292

9393
#[cfg(all(feature = "send", feature = "lua54"))]
94-
pub(crate) type WarnCallback = Box<dyn Fn(&Lua, &str, bool) -> Result<()> + Send>;
94+
pub(crate) type WarnCallback = XRc<dyn Fn(&Lua, &str, bool) -> Result<()> + Send>;
9595

9696
#[cfg(all(not(feature = "send"), feature = "lua54"))]
97-
pub(crate) type WarnCallback = Box<dyn Fn(&Lua, &str, bool) -> Result<()>>;
97+
pub(crate) type WarnCallback = XRc<dyn Fn(&Lua, &str, bool) -> Result<()>>;
9898

9999
/// A trait that adds `Send` requirement if `send` feature is enabled.
100100
#[cfg(feature = "send")]

tests/tests.rs

+7
Original file line numberDiff line numberDiff line change
@@ -1289,6 +1289,13 @@ fn test_warnings() -> Result<()> {
12891289
if matches!(*cause, Error::RuntimeError(ref err) if err == "warning error")
12901290
));
12911291

1292+
// Recursive warning
1293+
lua.set_warning_function(|lua, _, _| {
1294+
lua.warning("inner", false);
1295+
Ok(())
1296+
});
1297+
lua.warning("hello", false);
1298+
12921299
Ok(())
12931300
}
12941301

0 commit comments

Comments
 (0)