haikuwebkit/LayoutTests/js/dom/sequence-in-union-iterator-...

49 lines
1.6 KiB
HTML
Raw Permalink Normal View History

[WebIDL] @@iterator should only be accessed once when disambiguating a union type https://bugs.webkit.org/show_bug.cgi?id=172684 Patch by Sam Weinig <sam@webkit.org> on 2017-05-28 Reviewed by Yusuke Suzuki. Source/JavaScriptCore: * runtime/IteratorOperations.cpp: (JSC::iteratorMethod): (JSC::iteratorForIterable): * runtime/IteratorOperations.h: (JSC::forEachInIterable): Add additional iterator helpers to allow union + sequence conversion code to check for iterability by getting the iterator method, and iterate using that method later on. Source/WebCore: WebIDL specifies that when determining if the value you are converting to a union is a sequence, you must get the @@iterator property and, should it exist, use it to iterate the sequence. While we correctly accessing the property to make the determination, we were not passing it into the sequence conversion code, and thus the sequence conversion code re-accessed it, which is observable and wrong. This patch pipes the @@iterator method through the sequence conversion code to avoid this. Test: js/dom/sequence-in-union-iterator-access.html * bindings/js/JSDOMConvertSequences.h: (WebCore::Detail::GenericSequenceConverter::convert): (WebCore::Detail::NumericSequenceConverter::convertArray): (WebCore::Detail::NumericSequenceConverter::convert): (WebCore::Detail::SequenceConverter::convertArray): (WebCore::Detail::SequenceConverter::convert): (WebCore::Detail::SequenceConverter<IDLLong>::convert): (WebCore::Detail::SequenceConverter<IDLFloat>::convert): (WebCore::Detail::SequenceConverter<IDLUnrestrictedFloat>::convert): (WebCore::Detail::SequenceConverter<IDLDouble>::convert): (WebCore::Detail::SequenceConverter<IDLUnrestrictedDouble>::convert): (WebCore::Converter<IDLSequence<T>>::convert): (WebCore::Converter<IDLFrozenArray<T>>::convert): Add variants of convert that take a JSObject* (sequence) / JSValue (iterator method) rather than just the JSValue (sequence). To avoid too much duplication, split some parts of SequenceConverter and NumericSequenceConverter up so they could be reused. * bindings/js/JSDOMConvertUnion.h: - Fix incorrect step 3 (WebIDL got updated at some point and we didn't notice) to remove records. - Update sequence and FrozenArray checking/conversion to get the iterator method and pass it along, using the new ConditionalSequenceConverter helper which forwards to the new sequence converters that accept the iterator method. LayoutTests: * js/dom/sequence-in-union-iterator-access-expected.txt: Added. * js/dom/sequence-in-union-iterator-access.html: Added. Add test case showing that @@iterator is only accessed once when converting a sequence as part of a union. Canonical link: https://commits.webkit.org/189581@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@217529 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-05-29 01:30:58 +00:00
<!DOCTYPE html>
<html>
<head>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<script>
const originalIterator = Object.getOwnPropertyDescriptor(Array.prototype, Symbol.iterator);
test(() => {
let callCount = 0;
let array = [2.0, 0.0, 0.0, 2.0, 10.0, 10.0];
Object.defineProperty(array, Symbol.iterator, {
get() {
++callCount;
return originalIterator.value;
}
});
let matrix = new DOMMatrix(array);
assert_equals(callCount, 1, "@@iterator must only be accessed once.");
assert_equals(matrix.toString(), "matrix(2, 0, 0, 2, 10, 10)", "DOMMatrix constructor should work correctly.");
}, "@@iterator should only be accessed once, tested via replacement of @@iterator on instance.");
test((t) => {
t.add_cleanup(() => {
Object.defineProperty(Array.prototype, Symbol.iterator, originalIterator);
});
let callCount = 0;
const array = [2.0, 0.0, 0.0, 2.0, 10.0, 10.0];
Object.defineProperty(Array.prototype, Symbol.iterator, {
get() {
++callCount;
return originalIterator.value;
}
});
let matrix = new DOMMatrix(array);
assert_equals(callCount, 1, "@@iterator must only be accessed once.");
assert_equals(matrix.toString(), "matrix(2, 0, 0, 2, 10, 10)", "DOMMatrix constructor should work correctly.");
}, "@@iterator should only be accessed once, tested via replacement of @@iterator on prototype.");
</script>
</body>
</html>