diff options
author | Manish Goregaokar <manishsmail@gmail.com> | 2019-11-25 16:37:48 -0800 |
---|---|---|
committer | Manish Goregaokar <manishsmail@gmail.com> | 2019-11-25 19:56:14 -0800 |
commit | d233558b9b2e33eaa236714a6c6c486e893a94d6 (patch) | |
tree | 3489335d2bb128089e4b77f10a6f3c10cdab3177 /components/script/dom | |
parent | f1aa5d8dbdc32f6f474b09234558652b9bead686 (diff) | |
download | servo-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.py | 13 |
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 = (); |