mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-12 08:51:00 -06:00
JavaScript: apply takes fuel for each argument it reads
Function.prototype.apply reads up to 65,536 elements from an array-like object. Each element read now takes a unit of fuel, so a long list ends the run with the fuel limit as other loops in the interpreter do.
This commit is contained in:
@@ -1550,7 +1550,8 @@ impl Interp {
|
||||
let saved = self.temp_roots.len();
|
||||
let mut out = Vec::with_capacity(n);
|
||||
for i in 0..n {
|
||||
match self.get_from(*o, &index_key(u32::try_from(i).unwrap_or(u32::MAX)), list) {
|
||||
// Each element read takes fuel, so a long array-like list stays within the run's limits.
|
||||
match self.use_fuel().and_then(|()| self.get_from(*o, &index_key(u32::try_from(i).unwrap_or(u32::MAX)), list)) {
|
||||
Ok(v) => {
|
||||
self.temp_roots.push(v.clone());
|
||||
out.push(v);
|
||||
|
||||
@@ -391,6 +391,13 @@ fn shrinking_an_array_takes_fuel_for_each_property() {
|
||||
assert_eq!(realm.run("a.length = 1; a.length + a[0] + (99999 in a ? 1 : 0)"), Ok(JsValue::Number(1.0)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn apply_takes_fuel_for_each_argument_it_reads() {
|
||||
let mut realm = small(Limits { fuel: 1000, ..Limits::default() });
|
||||
assert_eq!(limit(&mut realm, "(function () {}).apply(null, {length: 65536});"), LimitKind::Fuel);
|
||||
assert_eq!(realm.run("(function () { return arguments.length; }).apply(null, {length: 100})"), Ok(JsValue::Number(100.0)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn declarations_check_the_heap_before_they_are_bound() {
|
||||
// Each script declares more than fits in the heap. The run ends with the heap limit before
|
||||
|
||||
Reference in New Issue
Block a user