diff --git a/Libraries/LibWeb/WebIDL/OverloadResolution.cpp b/Libraries/LibWeb/WebIDL/OverloadResolution.cpp index a4d762bdcc1..2362f3c3785 100644 --- a/Libraries/LibWeb/WebIDL/OverloadResolution.cpp +++ b/Libraries/LibWeb/WebIDL/OverloadResolution.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2022, Sam Atkins + * Copyright (c) 2024, Shannon Booth * * SPDX-License-Identifier: BSD-2-Clause */ @@ -77,7 +78,7 @@ JS::ThrowCompletionOr resolve_overload(JS::VM& vm, IDL::Effect auto distinguishing_argument_index = -1; // 7. Initialize method to undefined. - Optional method; + GC::Ptr method; // 8. If there is more than one entry in S, then set d to be the distinguishing argument index for the entries of S. if (overloads.size() > 1) @@ -253,7 +254,7 @@ JS::ThrowCompletionOr resolve_overload(JS::VM& vm, IDL::Effect overloads.remove_all_other_entries(); } - // FIXME: 9. Otherwise: if Type(V) is Object and there is an entry in S that has one of the following types at position i of its type list, + // 9. Otherwise: if Type(V) is Object and there is an entry in S that has one of the following types at position i of its type list, // - a sequence type // - a frozen array type // - a nullable version of any of the above types @@ -264,7 +265,28 @@ JS::ThrowCompletionOr resolve_overload(JS::VM& vm, IDL::Effect // 1. Let method be ? GetMethod(V, @@iterator). // } // method is not undefined, then remove from S all other entries. + else if (value.is_object() + && has_overload_with_argument_type_or_subtype_matching(overloads, i, [&vm, &method, &value](IDL::Type const& type) { + // - a sequence type + // FIXME: - a frozen array type + // - a nullable version of any of the above types + if (type.name() != "sequence") + return false; + // and after performing the following steps, + // { + // 1. Let method be ? GetMethod(V, @@iterator). + // } + // method is not undefined, then remove from S all other entries. + auto maybe_method = value.get_method(vm, vm.well_known_symbol_iterator()); + if (maybe_method.is_error() || maybe_method.value() == nullptr) + return false; + + method = *maybe_method.release_value(); + return true; + })) { + overloads.remove_all_other_entries(); + } // 10. Otherwise: if Type(V) is Object and there is an entry in S that has one of the following types at position i of its type list, // - a callback interface type // - a dictionary type @@ -375,7 +397,7 @@ JS::ThrowCompletionOr resolve_overload(JS::VM& vm, IDL::Effect auto const& callable = overloads.only_item(); // 14. If i = d and method is not undefined, then - if (i == distinguishing_argument_index && method.has_value()) { + if (i == distinguishing_argument_index && method) { // 1. Let V be args[i]. auto const& value = vm.argument(i); diff --git a/Tests/LibWeb/Text/expected/wpt-import/webmessaging/Channel_postMessage_clone_port_error.any.txt b/Tests/LibWeb/Text/expected/wpt-import/webmessaging/Channel_postMessage_clone_port_error.any.txt new file mode 100644 index 00000000000..ba4c49f7f5c --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/webmessaging/Channel_postMessage_clone_port_error.any.txt @@ -0,0 +1,11 @@ +Summary + +Harness status: OK + +Rerun + +Found 1 tests + +1 Pass +Details +Result Test Name MessagePass Test Description: Throw a DataCloneError if transfer array in postMessage contains source port. \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/wpt-import/webmessaging/Channel_postMessage_clone_port_error.any.html b/Tests/LibWeb/Text/input/wpt-import/webmessaging/Channel_postMessage_clone_port_error.any.html new file mode 100644 index 00000000000..cd8a947c744 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/webmessaging/Channel_postMessage_clone_port_error.any.html @@ -0,0 +1,15 @@ + + +postMessage() DataCloneError: cloning source port + + + + +
+ diff --git a/Tests/LibWeb/Text/input/wpt-import/webmessaging/Channel_postMessage_clone_port_error.any.js b/Tests/LibWeb/Text/input/wpt-import/webmessaging/Channel_postMessage_clone_port_error.any.js new file mode 100644 index 00000000000..cbee47270c4 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/webmessaging/Channel_postMessage_clone_port_error.any.js @@ -0,0 +1,14 @@ +// META: title=postMessage() DataCloneError: cloning source port + + var description = "Test Description: Throw a DataCloneError if transfer array in postMessage contains source port."; + + test(function() + { + var channel = new MessageChannel(); + channel.port1.start(); + + assert_throws_dom("DATA_CLONE_ERR", function() + { + channel.port1.postMessage("ports", [channel.port1]); + }); + }, description);