Skip to content

Commit

Permalink
Do not allow recursive warnings (Lua 5.4)
Browse files Browse the repository at this point in the history
  • Loading branch information
khvzak committed Feb 9, 2025
1 parent d1a587f commit c1f8abb
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 8 deletions.
13 changes: 7 additions & 6 deletions src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -703,18 +703,19 @@ impl Lua {
unsafe extern "C-unwind" fn warn_proc(ud: *mut c_void, msg: *const c_char, tocont: c_int) {
let extra = ud as *mut ExtraData;
callback_error_ext((*extra).raw_lua().state(), extra, |extra, _| {
let cb = mlua_expect!(
(*extra).warn_callback.as_ref(),
"no warning callback set in warn_proc"
);
let warn_callback = (*extra).warn_callback.clone();
let warn_callback = mlua_expect!(warn_callback, "no warning callback set in warn_proc");
if XRc::strong_count(&warn_callback) > 2 {
return Ok(());
}
let msg = StdString::from_utf8_lossy(CStr::from_ptr(msg).to_bytes());
cb((*extra).lua(), &msg, tocont != 0)
warn_callback((*extra).lua(), &msg, tocont != 0)
});
}

let lua = self.lock();
unsafe {
(*lua.extra.get()).warn_callback = Some(Box::new(callback));
(*lua.extra.get()).warn_callback = Some(XRc::new(callback));
ffi::lua_setwarnf(lua.state(), Some(warn_proc), lua.extra.get() as *mut c_void);
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,10 @@ pub(crate) type InterruptCallback = XRc<dyn Fn(&Lua) -> Result<VmState> + Send>;
pub(crate) type InterruptCallback = XRc<dyn Fn(&Lua) -> Result<VmState>>;

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

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

/// A trait that adds `Send` requirement if `send` feature is enabled.
#[cfg(feature = "send")]
Expand Down
7 changes: 7 additions & 0 deletions tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1289,6 +1289,13 @@ fn test_warnings() -> Result<()> {
if matches!(*cause, Error::RuntimeError(ref err) if err == "warning error")
));

// Recursive warning
lua.set_warning_function(|lua, _, _| {
lua.warning("inner", false);
Ok(())
});
lua.warning("hello", false);

Ok(())
}

Expand Down

0 comments on commit c1f8abb

Please sign in to comment.