Fix argument bugs with pcall / xpcall, add tests for it
This commit is contained in:
parent
f6cefca916
commit
f9f3d05804
29
src/tests.rs
29
src/tests.rs
|
@ -889,6 +889,35 @@ fn coroutine_panic() {
|
|||
thrd.resume::<_, ()>(()).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pcall_xpcall() {
|
||||
let lua = Lua::new();
|
||||
// make sure that we handle not enough arguments
|
||||
assert!(lua.exec::<()>("pcall()", None).is_err());
|
||||
assert!(lua.exec::<()>("xpcall()", None).is_err());
|
||||
assert!(lua.exec::<()>("xpcall(function() end)", None).is_err());
|
||||
|
||||
lua.exec::<()>(
|
||||
r#"
|
||||
pcall_error = nil
|
||||
_, pcall_error = pcall(error, "testerror")
|
||||
|
||||
xpcall_error = nil
|
||||
xpcall(error, function(err) xpcall_error = err end, "testerror")
|
||||
"#,
|
||||
None,
|
||||
).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
lua.globals().get::<_, String>("pcall_error").unwrap(),
|
||||
"testerror"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
lua.globals().get::<_, String>("xpcall_error").unwrap(),
|
||||
"testerror"
|
||||
);
|
||||
}
|
||||
|
||||
// Need to use compiletest-rs or similar to make sure these don't compile.
|
||||
/*
|
||||
|
|
14
src/util.rs
14
src/util.rs
|
@ -432,7 +432,11 @@ pub unsafe fn resume_with_traceback(
|
|||
|
||||
// A variant of pcall that does not allow lua to catch panic errors from callback_error
|
||||
pub unsafe extern "C" fn safe_pcall(state: *mut ffi::lua_State) -> c_int {
|
||||
if ffi::lua_pcall(state, ffi::lua_gettop(state) - 1, ffi::LUA_MULTRET, 0) != ffi::LUA_OK {
|
||||
let top = ffi::lua_gettop(state);
|
||||
if top == 0 {
|
||||
push_string(state, "not enough arguments to pcall");
|
||||
ffi::lua_error(state);
|
||||
} else if ffi::lua_pcall(state, top - 1, ffi::LUA_MULTRET, 0) != ffi::LUA_OK {
|
||||
if is_wrapped_panic(state, -1) {
|
||||
ffi::lua_error(state);
|
||||
}
|
||||
|
@ -459,10 +463,16 @@ pub unsafe extern "C" fn safe_xpcall(state: *mut ffi::lua_State) -> c_int {
|
|||
}
|
||||
}
|
||||
|
||||
let top = ffi::lua_gettop(state);
|
||||
if top < 2 {
|
||||
push_string(state, "not enough arguments to xpcall");
|
||||
ffi::lua_error(state);
|
||||
}
|
||||
|
||||
ffi::lua_pushvalue(state, 2);
|
||||
ffi::lua_pushcclosure(state, xpcall_msgh, 1);
|
||||
ffi::lua_copy(state, 1, 2);
|
||||
ffi::lua_insert(state, 1);
|
||||
ffi::lua_replace(state, 1);
|
||||
|
||||
let res = ffi::lua_pcall(state, ffi::lua_gettop(state) - 2, ffi::LUA_MULTRET, 1);
|
||||
if res != ffi::LUA_OK {
|
||||
|
|
Loading…
Reference in New Issue