mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-09 04:54:45 +00:00
JavaScript: the script a realm runs does not count against the re-entry limit
Limits::reentry bounds runs inside an operation (getters, setters, conversions, indirect eval). The top-level script took one of those slots, so a limit of 0 refused every script and a limit of 1 left no room for a getter. Only indirect eval now counts when it starts a global run.
This commit is contained in:
@@ -1810,7 +1810,10 @@ impl Interp {
|
||||
/// Indirect eval and scripts: runs `code` in the global environment and returns its
|
||||
/// completion value.
|
||||
pub(crate) fn run_global(&mut self, code: Rc<Code>, is_eval: bool) -> JsResult<Value> {
|
||||
if self.reentry >= self.limits.reentry {
|
||||
// Indirect eval runs inside an operation and counts against the re-entry limit; the
|
||||
// script a realm runs does not.
|
||||
let nested = usize::from(is_eval);
|
||||
if is_eval && self.reentry >= self.limits.reentry {
|
||||
return Err(Abrupt::Limit(LimitKind::Reentry));
|
||||
}
|
||||
self.charge_code(&code, declaration_bytes(&code).saturating_add(ENV_BYTES))?;
|
||||
@@ -1823,9 +1826,9 @@ impl Interp {
|
||||
};
|
||||
self.instantiate_global(&code, var_env, is_eval)?;
|
||||
self.push_code_frame(code, env, var_env, Value::Object(global), true)?;
|
||||
self.reentry += 1;
|
||||
self.reentry += nested;
|
||||
let r = self.execute();
|
||||
self.reentry -= 1;
|
||||
self.reentry -= nested;
|
||||
r
|
||||
}
|
||||
|
||||
|
||||
@@ -515,6 +515,17 @@ fn reentry_through_getters_ends_with_the_reentry_limit() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_script_itself_does_not_count_against_the_reentry_limit() {
|
||||
let mut realm = small(Limits { reentry: 0, ..Limits::default() });
|
||||
assert_eq!(realm.run("1 + 1"), Ok(JsValue::Number(2.0)));
|
||||
assert_eq!(limit(&mut realm, "var o = { get x() { return 1; } }; o.x"), LimitKind::Reentry);
|
||||
realm.set_limits(Limits { reentry: 1, ..Limits::default() });
|
||||
assert_eq!(realm.run("o.x"), Ok(JsValue::Number(1.0)));
|
||||
assert_eq!(realm.run("(0, eval)('2 + 2')"), Ok(JsValue::Number(4.0)));
|
||||
assert_eq!(limit(&mut realm, "var p = { get x() { return o.x; } }; p.x"), LimitKind::Reentry);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn memory_bombs_end_with_the_heap_limit() {
|
||||
let limits = Limits { heap_bytes: 4 << 20, ..Limits::default() };
|
||||
|
||||
Reference in New Issue
Block a user