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();
|
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.
|
// 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
|
// 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 {
|
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) {
|
if is_wrapped_panic(state, -1) {
|
||||||
ffi::lua_error(state);
|
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_pushvalue(state, 2);
|
||||||
ffi::lua_pushcclosure(state, xpcall_msgh, 1);
|
ffi::lua_pushcclosure(state, xpcall_msgh, 1);
|
||||||
ffi::lua_copy(state, 1, 2);
|
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);
|
let res = ffi::lua_pcall(state, ffi::lua_gettop(state) - 2, ffi::LUA_MULTRET, 1);
|
||||||
if res != ffi::LUA_OK {
|
if res != ffi::LUA_OK {
|
||||||
|
|
Loading…
Reference in New Issue