Always ensure LUA_MINSTACK available stack spaces on callback
Otherwise, cleanly error with an appropriate stack error. Part of an effort to ensure that it should not be possible to trigger a stack space assert.
This commit is contained in:
parent
4b6809c766
commit
0d5e45e800
|
@ -53,6 +53,7 @@ pub const LUA_REGISTRYINDEX: c_int = -LUAI_MAXSTACK - 1000;
|
||||||
pub const LUA_RIDX_MAINTHREAD: lua_Integer = 1;
|
pub const LUA_RIDX_MAINTHREAD: lua_Integer = 1;
|
||||||
pub const LUA_RIDX_GLOBALS: lua_Integer = 2;
|
pub const LUA_RIDX_GLOBALS: lua_Integer = 2;
|
||||||
pub const LUA_IDSIZE: c_int = 60;
|
pub const LUA_IDSIZE: c_int = 60;
|
||||||
|
pub const LUA_MINSTACK: c_int = 20;
|
||||||
// Not actually defined in lua.h / luaconf.h
|
// Not actually defined in lua.h / luaconf.h
|
||||||
pub const LUA_MAX_UPVALUES: c_int = 255;
|
pub const LUA_MAX_UPVALUES: c_int = 255;
|
||||||
|
|
||||||
|
|
24
src/lua.rs
24
src/lua.rs
|
@ -1013,15 +1013,13 @@ impl Lua {
|
||||||
ref_stack_slots: Default::default(),
|
ref_stack_slots: Default::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let args = lua.setup_callback_stack_slots();
|
let args = lua.setup_callback_stack()?;
|
||||||
|
|
||||||
let func = get_userdata::<Callback>(state, ffi::lua_upvalueindex(1));
|
let func = get_userdata::<Callback>(state, ffi::lua_upvalueindex(1));
|
||||||
|
|
||||||
let results = (*func)(&lua, args)?;
|
let results = (*func)(&lua, args)?;
|
||||||
let nresults = results.len() as c_int;
|
let nresults = results.len() as c_int;
|
||||||
|
|
||||||
check_stack_err(state, nresults)?;
|
check_stack_err(state, nresults)?;
|
||||||
|
|
||||||
for r in results {
|
for r in results {
|
||||||
lua.push_value(r);
|
lua.push_value(r);
|
||||||
}
|
}
|
||||||
|
@ -1175,8 +1173,9 @@ impl Lua {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up the stack slot area in a callback, returning all arguments on the stack as a
|
// Set up the stack slot area in a callback, returning all arguments on the stack as a
|
||||||
// MultiValue
|
// MultiValue. Also ensures that at least LUA_MINSTACK extra stack slots are available for use
|
||||||
fn setup_callback_stack_slots<'lua>(&'lua self) -> MultiValue<'lua> {
|
// in the callback.
|
||||||
|
fn setup_callback_stack<'lua>(&'lua self) -> Result<MultiValue<'lua>> {
|
||||||
unsafe {
|
unsafe {
|
||||||
check_stack(self.state, 2);
|
check_stack(self.state, 2);
|
||||||
|
|
||||||
|
@ -1243,15 +1242,19 @@ impl Lua {
|
||||||
args.push_front(Value::Thread(Thread(make_ref())));
|
args.push_front(Value::Thread(Thread(make_ref())));
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => rlua_panic!("LUA_TNONE in setup_callback_stack_slots"),
|
_ => rlua_panic!("LUA_TNONE in setup_callback_stack"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if nargs < REF_STACK_SIZE {
|
if nargs < REF_STACK_SIZE {
|
||||||
check_stack(self.state, REF_STACK_SIZE - nargs);
|
check_stack_err(self.state, REF_STACK_SIZE - nargs + ffi::LUA_MINSTACK)?;
|
||||||
ffi::lua_settop(self.state, REF_STACK_SIZE);
|
ffi::lua_settop(self.state, REF_STACK_SIZE);
|
||||||
args
|
Ok(args)
|
||||||
} else if nargs > REF_STACK_SIZE {
|
} else if nargs > REF_STACK_SIZE {
|
||||||
|
if nargs - REF_STACK_SIZE < ffi::LUA_MINSTACK {
|
||||||
|
check_stack_err(self.state, ffi::LUA_MINSTACK - (nargs - REF_STACK_SIZE))?;
|
||||||
|
}
|
||||||
|
|
||||||
// If the total number of arguments exceeds the ref stack area, pop off the rest of
|
// If the total number of arguments exceeds the ref stack area, pop off the rest of
|
||||||
// the arguments as normal.
|
// the arguments as normal.
|
||||||
let mut extra_args = Vec::new();
|
let mut extra_args = Vec::new();
|
||||||
|
@ -1260,9 +1263,10 @@ impl Lua {
|
||||||
extra_args.push(self.pop_value());
|
extra_args.push(self.pop_value());
|
||||||
}
|
}
|
||||||
extra_args.extend(args.into_vec_rev());
|
extra_args.extend(args.into_vec_rev());
|
||||||
MultiValue::from_vec_rev(extra_args)
|
Ok(MultiValue::from_vec_rev(extra_args))
|
||||||
} else {
|
} else {
|
||||||
args
|
check_stack_err(self.state, ffi::LUA_MINSTACK)?;
|
||||||
|
Ok(args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue