Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 0731b27c1b605241c9e23cceddae5af7717716ea
https://github.com/WebKit/WebKit/commit/0731b27c1b605241c9e23cceddae5af7717716ea
Author: Sosuke Suzuki <[email protected]>
Date: 2026-07-28 (Tue, 28 Jul 2026)
Changed paths:
A JSTests/stress/iterator-zip-object-prototype-pollution.js
M Source/JavaScriptCore/builtins/JSIteratorConstructor.js
Log Message:
-----------
[JSC] `Iterator.zip` should use null-prototype objects for `GetOptionsObject`
and the synthetic underlying iterator
https://bugs.webkit.org/show_bug.cgi?id=320312
Reviewed by Yusuke Suzuki.
Two places in the Joint Iteration builtins created ordinary objects backed by
Object.prototype, so polluting the prototype changed observable behavior:
1. getOptionsObject() returned `{}` instead of OrdinaryObjectCreate(null), so
with
options omitted, Get(options, "mode") / Get(options, "padding") read through
Object.prototype:
Object.defineProperty(Object.prototype, "mode", { value: "strict" });
Array.from(Iterator.zip([[1, 2, 3], [4, 5]])); // throws instead of
[[1, 4], [2, 5]]
2. iteratorZip() installed the synthetic underlying iterator's return() with an
ordinary [[Set]] on `{}`. A non-writable Object.prototype.return made every
Iterator.zip() call throw at creation, and an accessor silently swallowed the
assignment so IteratorCloseAll never ran.
Use @Object.@create(null) for both. This covers zip and zipKeyed since both go
through @iteratorZip.
Test: JSTests/stress/iterator-zip-object-prototype-pollution.js
* JSTests/stress/iterator-zip-object-prototype-pollution.js: Added.
(shouldBe):
(try.shouldBe.JSON.stringify.Array.from.Iterator.zipKeyed):
(try.b.makeIterator):
(set configurable):
* Source/JavaScriptCore/builtins/JSIteratorConstructor.js:
(linkTimeConstant.getOptionsObject):
Canonical link: https://commits.webkit.org/318061@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications