aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2019-11-25 16:37:48 -0800
committerManish Goregaokar <manishsmail@gmail.com>2019-11-25 19:56:14 -0800
commitd233558b9b2e33eaa236714a6c6c486e893a94d6 (patch)
tree3489335d2bb128089e4b77f10a6f3c10cdab3177 /components/script/dom
parentf1aa5d8dbdc32f6f474b09234558652b9bead686 (diff)
downloadservo-d233558b9b2e33eaa236714a6c6c486e893a94d6.tar.gz
servo-d233558b9b2e33eaa236714a6c6c486e893a94d6.zip
Fix iterator invalidation in our forEach implementation.
Diffstat (limited to 'components/script/dom')
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py13
1 files changed, 12 insertions, 1 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index fe3398417b2..39e8bfa275d 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -7408,7 +7408,16 @@ class CGIterableMethodGenerator(CGGeneric):
rooted!(in(*cx) let mut call_arg2 = UndefinedValue());
let mut call_args = vec![UndefinedValue(), UndefinedValue(), ObjectValue(*_obj)];
rooted!(in(*cx) let mut ignoredReturnVal = UndefinedValue());
- for i in 0..(*this).get_iterable_length() {
+
+ // This has to be a while loop since get_iterable_length() may change during
+ // the callback, and we need to avoid iterator invalidation.
+ //
+ // It is possible for this to loop infinitely, but that matches the spec
+ // and other browsers.
+ //
+ // https://heycam.github.io/webidl/#es-forEach
+ let mut i = 0;
+ while i < (*this).get_iterable_length() {
(*this).get_value_at_index(i).to_jsval(*cx, call_arg1.handle_mut());
(*this).get_key_at_index(i).to_jsval(*cx, call_arg2.handle_mut());
call_args[0] = call_arg1.handle().get();
@@ -7418,6 +7427,8 @@ class CGIterableMethodGenerator(CGGeneric):
ignoredReturnVal.handle_mut()) {
return false;
}
+
+ i += 1;
}
let result = ();