From 3da9d044be5abc2d9fb2fe9a26f3c9f0d995f76d Mon Sep 17 00:00:00 2001 From: Blink WPT Bot Date: Thu, 20 Jan 2022 09:31:56 -0800 Subject: [PATCH] AnonymousIframe: WPT BroadcastChannel #2 (#32346) The previous patch: https://chromium-review.googlesource.com/c/chromium/src/+/3371612/6 checked an AnonymousIframe and an Iframe wasn't sharing the same partition. This one test: - Two sibling same-origin anonymous iframe share the same partition. - Two same-origin nested anonymous iframe share the same partition. - Two same-origin anonymous iframe from different popup do not share the same partition. Bug: 1285331,1226469 Change-Id: I7ebc3a5bbb5e1f12d0ceaac9d89c1deb30174a37 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3379159 Reviewed-by: Andrew Williams Commit-Queue: Arthur Sonzogni Cr-Commit-Position: refs/heads/main@{#960946} Co-authored-by: Arthur Sonzogni --- .../broadcast-channel.tentative.window.js | 87 ++++++++++++++++++- .../anonymous-iframe/resources/common.js | 17 ++++ 2 files changed, 102 insertions(+), 2 deletions(-) diff --git a/html/cross-origin-embedder-policy/anonymous-iframe/broadcast-channel.tentative.window.js b/html/cross-origin-embedder-policy/anonymous-iframe/broadcast-channel.tentative.window.js index 255a7192099232..ad64ddf5f1f568 100644 --- a/html/cross-origin-embedder-policy/anonymous-iframe/broadcast-channel.tentative.window.js +++ b/html/cross-origin-embedder-policy/anonymous-iframe/broadcast-channel.tentative.window.js @@ -1,3 +1,4 @@ +// META: timeout=long // META: script=/common/get-host-info.sub.js // META: script=/common/utils.js // META: script=/common/dispatcher/dispatcher.js @@ -16,7 +17,15 @@ const emit_script = (key, message) => ` bc.postMessage("${message}"); `; -promise_test(async test => { +// For incorrect web browser implementations, some tests are failing by timing +// out. Calling this function turns timeout into errors. This informs developers +// about which precise test is failing. +const errorOnTimeout = test => + test.step_timeout(test.unreached_func("Timeout"), 9000); + +promise_test_parallel(async test => { + errorOnTimeout(test); + const origin = get_host_info().HTTPS_REMOTE_ORIGIN; const key_1 = token(); const key_2 = token(); @@ -53,4 +62,78 @@ promise_test(async test => { send(iframe_normal, emit_script(key_2, "msg_4")); assert_equals(await receive(queue_1), "msg_3"); assert_equals(await receive(queue_2), "msg_4"); -}) +}, "Anonymous iframe and normal iframe aren't in the same partition") + +promise_test_parallel(async test => { + errorOnTimeout(test); + + const origin = get_host_info().HTTPS_REMOTE_ORIGIN; + const key = token(); + + const iframe_anonymous_1 = newAnonymousIframe(origin); + const iframe_anonymous_2 = newAnonymousIframe(origin); + const queue = token(); + + send(iframe_anonymous_1 , listen_script(key, queue, queue)); + assert_equals(await receive(queue), "registered"); + send(iframe_anonymous_2, emit_script(key, "msg")); + assert_equals(await receive(queue), "msg"); +}, "Two sibling same-origin anonymous iframes are in the same partition"); + +promise_test_parallel(async test => { + errorOnTimeout(test); + + const origin = get_host_info().HTTPS_REMOTE_ORIGIN; + const key = token(); + const queue = token(); + + const iframe_anonymous_1 = newAnonymousIframe(origin); + send(iframe_anonymous_1, ` + const importScript = ${importScript}; + await importScript("/common/utils.js"); + await importScript("/html/cross-origin-embedder-policy/credentialless" + + "/resources/common.js"); + const newAnonymousIframe = ${newAnonymousIframe}; + const iframe_anonymous_2 = newAnonymousIframe("${origin}"); + send("${queue}", iframe_anonymous_2); + `); + const iframe_anonymous_2 = await receive(queue); + + send(iframe_anonymous_1 , listen_script(key, queue, queue)); + assert_equals(await receive(queue), "registered"); + send(iframe_anonymous_2, emit_script(key, "msg")); + assert_equals(await receive(queue), "msg"); +}, "Nested same-origin anonymous iframe are in the same partition"); + +promise_test_parallel(async test => { + errorOnTimeout(test); + + const origin = get_host_info().HTTPS_REMOTE_ORIGIN; + const key = token(); + const queue = token(); + + const iframe_anonymous_1 = newAnonymousIframe(origin); + const popup = newPopup(origin); + send(popup, ` + const importScript = ${importScript}; + await importScript("/common/utils.js"); + await importScript("/html/cross-origin-embedder-policy/credentialless" + + "/resources/common.js"); + const newAnonymousIframe = ${newAnonymousIframe}; + send("${queue}", newAnonymousIframe("${origin}")); + `); + const iframe_anonymous_2 = await receive(queue); + + const unexpected_queue = token(); + receive(unexpected_queue).then(test.unreached_func( + "Two same-origin anonymous iframe in different windows shouldn't be able " + + "to communicate using BroadcastChannel")); + + send(iframe_anonymous_1 , listen_script(key, queue, unexpected_queue)); + assert_equals(await receive(queue), "registered"); + await send(iframe_anonymous_2, emit_script(key, "msg")); + + // Wait a bit to give the opportunity for unexpected message to be received. + await new Promise(r => test.step_timeout(r, 500)); +}, "Two anonymous iframes in different windows do not share the same " + + "partition"); diff --git a/html/cross-origin-embedder-policy/anonymous-iframe/resources/common.js b/html/cross-origin-embedder-policy/anonymous-iframe/resources/common.js index e11e2307defd6e..4fd12a6a747414 100644 --- a/html/cross-origin-embedder-policy/anonymous-iframe/resources/common.js +++ b/html/cross-origin-embedder-policy/anonymous-iframe/resources/common.js @@ -19,3 +19,20 @@ const newIframe = (child_origin) => { document.body.appendChild(iframe); return sub_document_token; }; + +// Create a popup. The new document will execute any scripts sent toward the +// token it returns. +const newPopup = (origin) => { + const popup_token = token(); + const popup = window.open(origin + executor_path + `&uuid=${popup_token}`); + return popup_token; +}; + +const importScript = (url) => { + const script = document.createElement("script"); + script.type = "text/javascript"; + script.src = url; + const loaded = new Promise(resolve => script.onload = resolve); + document.body.appendChild(script); + return loaded; +}