From d233558b9b2e33eaa236714a6c6c486e893a94d6 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 25 Nov 2019 16:37:48 -0800 Subject: [PATCH] Fix iterator invalidation in our forEach implementation. --- .../script/dom/bindings/codegen/CodegenRust.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) 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 = ();