diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:47:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:47:29 +0000 |
commit | 0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d (patch) | |
tree | a31f07c9bcca9d56ce61e9a1ffd30ef350d513aa /testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data | |
parent | Initial commit. (diff) | |
download | firefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.tar.xz firefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.zip |
Adding upstream version 115.8.0esr.upstream/115.8.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data')
90 files changed, 2105 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/cross-origin-transfer-resizable-arraybuffer.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/cross-origin-transfer-resizable-arraybuffer.html new file mode 100644 index 0000000000..2b21a1459d --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/cross-origin-transfer-resizable-arraybuffer.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<title>postMessage transfer ArrayBuffer cross origin iframe</title> +<script src='/resources/testharness.js'></script> +<script src='/resources/testharnessreport.js'></script> +<script src='/common/get-host-info.sub.js'></script> + +<script> + +async_test(t => { + const oopif = document.createElement('iframe'); + + window.addEventListener('message', t.step_func((e) => { + if (e.data === 'started') { + const rab = new ArrayBuffer(32, { maxByteLength: 1024 }); + oopif.contentWindow.postMessage(rab, '*', [rab]); + } else { + assert_equals(e.data, 'byteLength=32,maxByteLength=1024,resizable=true'); + t.done(); + } + })); + + window.addEventListener('load', () => { + oopif.src = `${get_host_info().HTTP_REMOTE_ORIGIN}/html/infrastructure/safe-passing-of-structured-data/resources/iframe-resizable-arraybuffer-helper.html`; + document.body.appendChild(oopif); + }); +}, 'postMessaging resizable ArrayBuffer to OOPIF'); + +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.js b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.js new file mode 100644 index 0000000000..6ba17f7a89 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.js @@ -0,0 +1,16 @@ +// META: global=window,worker +// META: script=/common/sab.js +// META: script=/html/webappapis/structured-clone/structured-clone-battery-of-tests.js +// META: script=/html/webappapis/structured-clone/structured-clone-battery-of-tests-with-transferables.js +// META: script=/html/webappapis/structured-clone/structured-clone-battery-of-tests-harness.js + +runStructuredCloneBatteryOfTests({ + structuredClone(data, transfer) { + return new Promise(resolve => { + const channel = new MessageChannel(); + channel.port2.onmessage = ev => resolve(ev.data.data); + channel.port1.postMessage({data, transfer}, transfer); + }); + }, + hasDocument : self.GLOBAL.isWindow() +}); diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/resources/echo-iframe.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/resources/echo-iframe.html new file mode 100644 index 0000000000..c4fd5824a1 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/resources/echo-iframe.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>A test page that echos back anything postMessaged to it to its parent</title> + +<script> +"use strict"; + +window.onmessage = ({ data }) => { + parent.postMessage(data, "*"); +}; +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/resources/echo-iframe.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/resources/echo-iframe.html.headers new file mode 100644 index 0000000000..4e798cd9f5 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/resources/echo-iframe.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Embedder-Policy: require-corp +Cross-Origin-Resource-Policy: cross-origin diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/resources/echo-worker.js b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/resources/echo-worker.js new file mode 100644 index 0000000000..cbbde8a73c --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/resources/echo-worker.js @@ -0,0 +1,5 @@ +"use strict"; + +self.onmessage = ({ data }) => { + self.postMessage(data); +}; diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/resources/echo-worker.js.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/resources/echo-worker.js.headers new file mode 100644 index 0000000000..6604450991 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/resources/echo-worker.js.headers @@ -0,0 +1 @@ +Cross-Origin-Embedder-Policy: require-corp diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/resources/iframe-resizable-arraybuffer-helper.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/resources/iframe-resizable-arraybuffer-helper.html new file mode 100644 index 0000000000..378c953fbe --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/resources/iframe-resizable-arraybuffer-helper.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<script> + +window.addEventListener('message', (e) => { + const buffer = e.data; + e.source.postMessage(`byteLength=${buffer.byteLength},maxByteLength=${buffer.maxByteLength},resizable=${buffer.resizable}`, '*'); +}); + +window.parent.postMessage('started', '*'); + +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/resources/post-parent-type-error.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/resources/post-parent-type-error.html new file mode 100644 index 0000000000..d6713c4192 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/resources/post-parent-type-error.html @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Helper that posts its parent a TypeError</title> + +<script> +window.doIt = () => { + parent.postMessage(new TypeError("!!"), "*"); +}; +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/blob-data.https.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/blob-data.https.html new file mode 100644 index 0000000000..bfcc8b61ca --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/blob-data.https.html @@ -0,0 +1,132 @@ +<!doctype html> +<meta charset=utf-8> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id=log></div> +<script> +const url = new URL("./", self.location); + +function httpWorkerIncrementerTest(name) { + return ` +promise_test(t => { + const worker = new Worker("${url.href}resources/incrementer-worker.js"); + + return testSharingViaIncrementerScript(t, worker, "parent worker", worker, "sub-worker"); +}, "${name}: postMessaging to a dedicated HTTP sub-worker allows them to see each others' modifications"); +`; +} + +function blobWorkerIncrementerTest(name, origin = "null") { + return ` +promise_test(t => { + const worker = new Worker(URL.createObjectURL(new Blob([\` +const view = new Uint8Array(new SharedArrayBuffer(1)); +self.onmessage = () => { + const succeeded = (view[0] === 1); + self.postMessage({ succeeded }); +}; +self.postMessage({ origin: self.origin, view }); +\`], { type: "text/javascript" }))); + + return new Promise((resolve, reject) => { + /* Initially the sub-worker gives us an object containing an origin and a view on a shared + // buffer. We then modify the shared buffer through the buffer and tell the sub-worker to + // "continue". The sub-worker verifies the modification and relays whether it succeeded. + */ + worker.onmessage = t.step_func(({ data }) => { + if ("succeeded" in data) { + assert_true(data.succeeded); + resolve(); + } else { + assert_equals(data.origin, "${origin}"); + assert_equals(data.view[0], 0); + data.view[0] = 1; + worker.postMessage("continue"); + } + }); + worker.onmessageerror = reject; + }); +}, "${name}: postMessaging to a dedicated blob sub-worker allows them to see each others' modifications"); +`; +} + +function propertyTests(name, crossOriginIsolated) { + return ` +test(() => { + assert_equals(self.origin, self.location.origin); +}, "${name}: self.origin"); + +test(() => { + assert_equals(self.crossOriginIsolated, ${crossOriginIsolated}); +}, "${name}: self.crossOriginIsolated"); + +test(() => { + assert_true(self.isSecureContext); +}, "${name}: self.isSecureContext"); +`; +} + +const workerScript = ` +importScripts("${url.origin}/resources/testharness.js"); +importScripts("${url.href}resources/test-incrementer.js"); + +${httpWorkerIncrementerTest("blob worker")} + +${blobWorkerIncrementerTest("blob worker", self.location.origin)} + +${propertyTests("blob worker", true)} + +done(); +`; + +fetch_tests_from_worker(new Worker(URL.createObjectURL(new Blob([workerScript], { type: "text/javascript" })))); + +const frameScript = ` +<!doctype html> +<script src=${url.origin}/resources/testharness.js><\/script> +<script src=${url.href}resources/test-incrementer.js><\/script> +<script> +${httpWorkerIncrementerTest("blob frame")} + +${blobWorkerIncrementerTest("blob frame", self.location.origin)} + +${propertyTests("blob frame", true)} +<\/script> +`; + +const frame = document.body.appendChild(document.createElement("iframe")); +frame.src = URL.createObjectURL(new Blob([frameScript], { type: "text/html" })); +frame.style = "display:none"; +fetch_tests_from_window(frame.contentWindow); + +const dataWorkerScript = ` +importScripts("${url.origin}/resources/testharness.js?pipe=header(Cross-Origin-Resource-Policy,cross-origin)"); + +/* Cannot use httpWorkerIncrementerTest() here as the HTTP URL is not same origin. */ + +${blobWorkerIncrementerTest("data worker")} + +${propertyTests("data worker", false)} + +done(); +`; + +fetch_tests_from_worker(new Worker(`data:,${dataWorkerScript}`)); + +const dataFrameScript = ` +<!doctype html> +<script src=${url.origin}/resources/testharness.js?pipe=header(Cross-Origin-Resource-Policy,cross-origin)><\/script> +<script> +/* Cannot use httpWorkerIncrementerTest() here as the HTTP URL is not same origin. */ + +${blobWorkerIncrementerTest("data frame")} + +${propertyTests("data frame", true)} +<\/script> +`; + +const dataFrame = document.body.appendChild(document.createElement("iframe")); +dataFrame.src = `data:text/html,${dataFrameScript}`; +dataFrame.style = "display:none"; +fetch_tests_from_window(dataFrame.contentWindow); +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/blob-data.https.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/blob-data.https.html.headers new file mode 100644 index 0000000000..63b60e490f --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/blob-data.https.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success-and-failure.https.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success-and-failure.https.html new file mode 100644 index 0000000000..8902de49cf --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success-and-failure.https.html @@ -0,0 +1,35 @@ +<!doctype html> +<title>SharedArrayBuffer cannot cross agent clusters, BroadcastChannel edition</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script> +async_test(t => { + const channel = new BroadcastChannel("anne was here"), + dw = new Worker("resources/broadcastchannel-worker.js"), + sw = new SharedWorker("resources/broadcastchannel-sharedworker.js"); + let startCounter = 0, + dwStatus = "unknown", + swStatus = "unknown"; + + channel.onmessage = t.step_func(({ data }) => { + if(data === "hi") { + startCounter++; + if(startCounter === 2) { + const sab = new SharedArrayBuffer(); + channel.postMessage(sab); + } else if(startCounter > 2) { + assert_unreached(); + } + } else if(data === "dw-success") { + dwStatus = "success"; + } else if(data === "sw-success") { + swStatus = "success"; + } else { + assert_unreached(); + } + if(dwStatus === "success" && swStatus === "success") { + t.done(); + } + }); +}); +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success-and-failure.https.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success-and-failure.https.html.headers new file mode 100644 index 0000000000..63b60e490f --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success-and-failure.https.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success.https.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success.https.html new file mode 100644 index 0000000000..d3e9956368 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success.https.html @@ -0,0 +1,55 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Structured cloning of SharedArrayBuffers: BroadcastChannel within the same agent cluster</title> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#structuredserialize"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#broadcasting-to-other-browsing-contexts"> +<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/utils.js"></script> <!-- Use token() to allow running tests in parallel --> + +<div id="log"></div> + +<script> +"use strict"; + +promise_test(t => { + const channelName = token(); + return Promise.all([ + createIFrame(`resources/broadcastchannel-iframe.html?channel=${channelName}&index=0`), + createIFrame(`resources/broadcastchannel-iframe.html?channel=${channelName}&index=1`), + createIFrame(`resources/broadcastchannel-iframe.html?channel=${channelName}&index=2`) + ]).then(() => { + const sab = new SharedArrayBuffer(3); + const view = new Uint8Array(sab); + const channel = new BroadcastChannel(channelName); + + return new Promise(resolve => { + let soFar = 0; + channel.onmessage = t.step_func(({ data: { i } }) => { + assert_in_array(i, [0, 1, 2], "Any message events must come from expected sources"); + ++soFar; + + if (soFar === 3) { + assert_equals(view[0], 1, "The first iframe must have set view[0] to 1"); + assert_equals(view[1], 2, "The second iframe must have set view[1] to 2"); + assert_equals(view[2], 3, "The third iframe must have set view[2] to 3"); + resolve(); + } + }); + + channel.postMessage({ sab }); + }); + }); +}); + +function createIFrame(src) { + return new Promise((resolve, reject) => { + const iframe = document.createElement("iframe"); + iframe.src = src; + iframe.onload = () => resolve(iframe); + iframe.onerror = () => reject(`iframe with URL ${src} failed to load`); + document.body.appendChild(iframe); + }); +} +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success.https.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success.https.html.headers new file mode 100644 index 0000000000..63b60e490f --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success.https.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/identity-not-preserved.https.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/identity-not-preserved.https.html new file mode 100644 index 0000000000..869f49043e --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/identity-not-preserved.https.html @@ -0,0 +1,68 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>SharedArrayBuffers, when cloned, do not give back the same object</title> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#structuredserialize"> +<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/utils.js"></script> +<script src="resources/test-sab.js"></script> + +<div id="log"></div> + +<script> +"use strict"; + +async_test(t => { + const testId = token(); + const sab = new SharedArrayBuffer(1); + window.addEventListener("message", t.step_func(({ data }) => { + if (data.testId !== testId) { + return; + } + + assertSABsHaveSameBackingBlock(sab, data.sab); + + t.done(); + })); + + window.postMessage({ testId, sab }, "*"); +}, "postMessaging to this window does not give back the same SharedArrayBuffer (but does use the same backing block)"); + +async_test(t => { + const testId = token(); + const sab = new SharedArrayBuffer(); + const worker = new Worker("../resources/echo-worker.js"); + + worker.addEventListener("message", t.step_func(({ data }) => { + if (data.testId !== testId) { + return; + } + + assert_not_equals(data.sab, sab); + t.done(); + })); + + worker.postMessage({ testId, sab }); +}, "postMessaging to a worker and back does not give back the same SharedArrayBuffer"); + +async_test(t => { + const testId = token(); + const sab = new SharedArrayBuffer(); + window.addEventListener("message", t.step_func(({ data }) => { + if (data.testId !== testId) { + return; + } + + assert_not_equals(data.sab, sab); + t.done(); + })); + + const iframe = document.createElement("iframe"); + iframe.onload = t.step_func(() => { + iframe.contentWindow.postMessage({ testId, sab }, "*"); + }); + iframe.src = "../resources/echo-iframe.html"; + document.body.appendChild(iframe); +}, "postMessaging to an iframe and back does not give back the same SharedArrayBuffer"); +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/identity-not-preserved.https.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/identity-not-preserved.https.html.headers new file mode 100644 index 0000000000..63b60e490f --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/identity-not-preserved.https.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https.html new file mode 100644 index 0000000000..dd221502b6 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https.html @@ -0,0 +1,8 @@ +<!doctype html> +<meta charset=utf-8> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id=log></div> +<script> +fetch_tests_from_worker(new SharedWorker("resources/nested-worker-success.js")); +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https.html.headers new file mode 100644 index 0000000000..63b60e490f --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.https.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.https.html new file mode 100644 index 0000000000..aeee3705ae --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.https.html @@ -0,0 +1,8 @@ +<!doctype html> +<meta charset=utf-8> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id=log></div> +<script> +fetch_tests_from_worker(new Worker("resources/nested-worker-success.js")); +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.https.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.https.html.headers new file mode 100644 index 0000000000..63b60e490f --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.https.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.js b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.js new file mode 100644 index 0000000000..0db16fd6f7 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.js @@ -0,0 +1,33 @@ +// META: global=window,worker + +test(() => { + // See https://github.com/whatwg/html/issues/5380 for why not `new SharedArrayBuffer()` + assert_equals(globalThis.SharedArrayBuffer, undefined); + assert_false("SharedArrayBuffer" in globalThis); +}, "SharedArrayBuffer constructor does not exist without COOP+COEP"); + +test(() => { + // See https://github.com/whatwg/html/issues/5380 for why not `new SharedArrayBuffer()` + const sab = new WebAssembly.Memory({ shared:true, initial:1, maximum:1 }).buffer; + const channel = new MessageChannel(); + assert_throws_dom("DataCloneError", () => channel.port1.postMessage(sab)); +}, "SharedArrayBuffer over MessageChannel without COOP+COEP"); + +test(() => { + // See https://github.com/whatwg/html/issues/5380 for why not `new SharedArrayBuffer()` + const sab = new WebAssembly.Memory({ shared:true, initial:1, maximum:1 }).buffer; + const channel = new BroadcastChannel("Is mir egal"); + assert_throws_dom("DataCloneError", () => channel.postMessage(sab)); +}, "SharedArrayBuffer over BroadcastChannel without COOP+COEP"); + +if (self.GLOBAL.isWindow()) { + test(() => { + // See https://github.com/whatwg/html/issues/5380 for why not `new SharedArrayBuffer()` + const sab = new WebAssembly.Memory({ shared:true, initial:1, maximum:1 }).buffer; + assert_throws_dom("DataCloneError", () => self.postMessage(sab)); + }, "SharedArrayBuffer over postMessage() without COOP+COEP"); +} + +test(() => { + assert_false(self.crossOriginIsolated); +}, "Bonus: self.crossOriginIsolated"); diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-transferring.https.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-transferring.https.html new file mode 100644 index 0000000000..dfa57fa200 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-transferring.https.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>SharedArrayBuffers cannot be transferred</title> +<link rel="help" href="https://html.spec.whatwg.org/#structuredclone"> +<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script> +"use strict"; + +test(() => { + const sab = new SharedArrayBuffer(); + assert_throws_dom("DataCloneError", () => window.postMessage(sab, "*", [sab])); + assert_throws_dom("DataCloneError", () => window.postMessage("test", "*", [sab])); +}, "Trying to transfer a SharedArrayBuffer to this window throws"); + +test(() => { + const sab = new SharedArrayBuffer(); + const worker = new Worker("../resources/echo-worker.js"); + assert_throws_dom("DataCloneError", () => worker.postMessage(sab, [sab])); + assert_throws_dom("DataCloneError", () => worker.postMessage("test", [sab])); +}, "Trying to transfer a SharedArrayBuffer to a worker throws"); + +test(() => { + const sab = new SharedArrayBuffer(); + const channel = new MessageChannel(); + assert_throws_dom("DataCloneError", () => channel.port1.postMessage(sab, [sab])); + assert_throws_dom("DataCloneError", () => channel.port1.postMessage("test", [sab])); +}, "Trying to transfer a SharedArrayBuffer through a MessagePort throws"); +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-transferring.https.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-transferring.https.html.headers new file mode 100644 index 0000000000..63b60e490f --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-transferring.https.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/blank.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/blank.html new file mode 100644 index 0000000000..eec1b2cc8e --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/blank.html @@ -0,0 +1,2 @@ +<!DOCTYPE html> +<title>Used as a service worker-controlled iframe</title> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/blank.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/blank.html.headers new file mode 100644 index 0000000000..6604450991 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/blank.html.headers @@ -0,0 +1 @@ +Cross-Origin-Embedder-Policy: require-corp diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-iframe.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-iframe.html new file mode 100644 index 0000000000..02b9bcbbe8 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-iframe.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>A test page that messes with a given SharedArrayBuffer sent from a BroadcastChannel</title> + +<script> +"use strict"; +const query = new URLSearchParams(location.search); +const channel = new BroadcastChannel(query.get("channel")); +const i = Number(query.get("index")); + +channel.onmessage = e => { + const sab = e.data.sab; + if (sab === undefined) { + // We only care about "broadcasts" from the window + return; + } + + const view = new Uint8Array(sab); + view[i] = i + 1; + channel.postMessage({ i }); +}; +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-iframe.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-iframe.html.headers new file mode 100644 index 0000000000..4e798cd9f5 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-iframe.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Embedder-Policy: require-corp +Cross-Origin-Resource-Policy: cross-origin diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-sharedworker.js b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-sharedworker.js new file mode 100644 index 0000000000..310e0e9358 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-sharedworker.js @@ -0,0 +1,7 @@ +const channel = new BroadcastChannel("anne was here"); +channel.onmessageerror = ({ data }) => { + if(data === null) { + channel.postMessage("sw-success"); + } +} +channel.postMessage("hi"); diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-sharedworker.js.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-sharedworker.js.headers new file mode 100644 index 0000000000..6604450991 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-sharedworker.js.headers @@ -0,0 +1 @@ +Cross-Origin-Embedder-Policy: require-corp diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-worker.js b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-worker.js new file mode 100644 index 0000000000..36369cde50 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-worker.js @@ -0,0 +1,9 @@ +const channel = new BroadcastChannel("anne was here"); +channel.onmessage = ({ data }) => { + if(data === "hi" || data === "sw-success") { + return; + } else if(data instanceof SharedArrayBuffer) { + channel.postMessage("dw-success"); + } +} +channel.postMessage("hi"); diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-worker.js.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-worker.js.headers new file mode 100644 index 0000000000..6604450991 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/broadcastchannel-worker.js.headers @@ -0,0 +1 @@ +Cross-Origin-Embedder-Policy: require-corp diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-domain-failure.sub.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-domain-failure.sub.html new file mode 100644 index 0000000000..0cdb8b5f59 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-domain-failure.sub.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>A test page that postMessage a SharedArrayBuffer to the parent and also sets document.domain</title> + +<script> +"use strict"; + +document.domain = "{{host}}"; +parent.postMessage({name: "domain", value: document.domain}, "*"); +parent.postMessage( + {name: "crossOriginIsolated", value: self.crossOriginIsolated}, "*"); +parent.postMessage( + {name: "hasSharedArrayBuffer", value: Boolean(self.SharedArrayBuffer)}, "*"); +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-domain-failure.sub.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-domain-failure.sub.html.headers new file mode 100644 index 0000000000..56d0ac3428 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-domain-failure.sub.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Embedder-Policy: require-corp +Cross-Origin-Resource-Policy: same-site diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-failure.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-failure.html new file mode 100644 index 0000000000..2c33dba79a --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-failure.html @@ -0,0 +1,3 @@ +<script> +parent.postMessage(new SharedArrayBuffer(10), "*"); +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-failure.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-failure.html.headers new file mode 100644 index 0000000000..4e798cd9f5 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-failure.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Embedder-Policy: require-corp +Cross-Origin-Resource-Policy: cross-origin diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-messagechannel-complex.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-messagechannel-complex.html new file mode 100644 index 0000000000..1666a98458 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-messagechannel-complex.html @@ -0,0 +1,6 @@ +<!DOCTYPE html> +<script> + const channel = new MessageChannel(); + window.parent.postMessage({ state: "port1", data: channel.port1 }, '*', [channel.port1]); + window.onmessage = () => window.parent.postMessage({ state: "port2", data: channel.port2 }, '*', [channel.port2]); +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-messagechannel-complex.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-messagechannel-complex.html.headers new file mode 100644 index 0000000000..4e798cd9f5 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-messagechannel-complex.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Embedder-Policy: require-corp +Cross-Origin-Resource-Policy: cross-origin diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-messagechannel-failure.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-messagechannel-failure.html new file mode 100644 index 0000000000..c6896762bc --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-messagechannel-failure.html @@ -0,0 +1,7 @@ +<!DOCTYPE html> +<script> + const channel = new MessageChannel(); + window.parent.postMessage(channel.port2, '*', [channel.port2]); + channel.port1.onmessage = e => { alert(e.data); channel.port1.postMessage("message event received") }; + channel.port1.onmessageerror = () => channel.port1.postMessage("messageerror event received"); +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-messagechannel-failure.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-messagechannel-failure.html.headers new file mode 100644 index 0000000000..4e798cd9f5 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-messagechannel-failure.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Embedder-Policy: require-corp +Cross-Origin-Resource-Policy: cross-origin diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-messagechannel-site-failure.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-messagechannel-site-failure.html new file mode 100644 index 0000000000..95a610f928 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-messagechannel-site-failure.html @@ -0,0 +1,7 @@ +<!DOCTYPE html> +<script> + const channel = new MessageChannel(); + window.parent.postMessage(channel.port2, '*', [channel.port2]); + channel.port1.onmessage = e => { channel.port1.postMessage("message event received") }; + channel.port1.onmessageerror = () => channel.port1.postMessage("messageerror event received"); +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-messagechannel-site-failure.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-messagechannel-site-failure.html.headers new file mode 100644 index 0000000000..56d0ac3428 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-messagechannel-site-failure.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Embedder-Policy: require-corp +Cross-Origin-Resource-Policy: same-site diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe-messagechannel.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe-messagechannel.html new file mode 100644 index 0000000000..6f3f284ae2 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe-messagechannel.html @@ -0,0 +1,10 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>A test page that messes with a given SharedArrayBuffer via MessageChannel</title> +<script src="test-incrementer.js"></script> + +<script> + const channel = new MessageChannel(); + window.parent.postMessage(channel.port2, '*', [channel.port2]); + setupDestinationIncrementer(channel.port1, channel.port1); +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe-messagechannel.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe-messagechannel.html.headers new file mode 100644 index 0000000000..4e798cd9f5 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe-messagechannel.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Embedder-Policy: require-corp +Cross-Origin-Resource-Policy: cross-origin diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe.html new file mode 100644 index 0000000000..6f27ad7d5b --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe.html @@ -0,0 +1,10 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>A test page that messes with a given SharedArrayBuffer</title> +<script src="test-incrementer.js"></script> + +<script> +"use strict"; + +setupDestinationIncrementer(self, parent, "*"); +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe.html.headers new file mode 100644 index 0000000000..4e798cd9f5 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-iframe.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Embedder-Policy: require-corp +Cross-Origin-Resource-Policy: cross-origin diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-popup.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-popup.html new file mode 100644 index 0000000000..e583b5c416 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-popup.html @@ -0,0 +1,10 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>A test page that messes with a given SharedArrayBuffer</title> +<script src="test-incrementer.js"></script> + +<script> +"use strict"; + +setupDestinationIncrementer(self, opener, "*"); +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-popup.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-popup.html.headers new file mode 100644 index 0000000000..63b60e490f --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-popup.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-worker-with-channel.js b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-worker-with-channel.js new file mode 100644 index 0000000000..c74fd26d3f --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-worker-with-channel.js @@ -0,0 +1,7 @@ +"use strict"; +importScripts("./test-incrementer.js"); + +self.onmessage = ({ data }) => { + // data will be a MessagePort + setupDestinationIncrementer(data, data); +}; diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-worker-with-channel.js.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-worker-with-channel.js.headers new file mode 100644 index 0000000000..6604450991 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-worker-with-channel.js.headers @@ -0,0 +1 @@ +Cross-Origin-Embedder-Policy: require-corp diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-worker.js b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-worker.js new file mode 100644 index 0000000000..5801bd2b97 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-worker.js @@ -0,0 +1,4 @@ +"use strict"; +importScripts("./test-incrementer.js"); + +setupDestinationIncrementer(self, self); diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-worker.js.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-worker.js.headers new file mode 100644 index 0000000000..6604450991 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/incrementer-worker.js.headers @@ -0,0 +1 @@ +Cross-Origin-Embedder-Policy: require-corp diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-1.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-1.html new file mode 100644 index 0000000000..fe93cc0c4b --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-1.html @@ -0,0 +1,5 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Nesting level 1</title> + +<iframe src="nested-iframe-2.html"></iframe> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-1.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-1.html.headers new file mode 100644 index 0000000000..4e798cd9f5 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-1.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Embedder-Policy: require-corp +Cross-Origin-Resource-Policy: cross-origin diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-2.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-2.html new file mode 100644 index 0000000000..fad52ce9de --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-2.html @@ -0,0 +1,5 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Nesting level 2</title> + +<iframe src="nested-iframe-3.html"></iframe> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-2.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-2.html.headers new file mode 100644 index 0000000000..4e798cd9f5 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-2.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Embedder-Policy: require-corp +Cross-Origin-Resource-Policy: cross-origin diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-3.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-3.html new file mode 100644 index 0000000000..7971022b2c --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-3.html @@ -0,0 +1,5 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Nesting level 3</title> + +<iframe src="nested-iframe-4-incrementer.html"></iframe> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-3.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-3.html.headers new file mode 100644 index 0000000000..4e798cd9f5 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-3.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Embedder-Policy: require-corp +Cross-Origin-Resource-Policy: cross-origin diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-4-incrementer.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-4-incrementer.html new file mode 100644 index 0000000000..d374515bdc --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-4-incrementer.html @@ -0,0 +1,10 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>A test page that messes with a given SharedArrayBuffer, nested 4 levels deep in iframes</title> +<script src="test-incrementer.js"></script> + +<script> +"use strict"; + +setupDestinationIncrementer(self, parent.parent.parent.parent.parent, "*"); +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-4-incrementer.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-4-incrementer.html.headers new file mode 100644 index 0000000000..4e798cd9f5 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-iframe-4-incrementer.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Embedder-Policy: require-corp +Cross-Origin-Resource-Policy: cross-origin diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js new file mode 100644 index 0000000000..ffc3708acb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js @@ -0,0 +1,14 @@ +importScripts("/resources/testharness.js"); +importScripts("test-incrementer.js"); + +promise_test(t => { + const worker = new Worker("incrementer-worker.js"); + + return testSharingViaIncrementerScript(t, worker, "parent worker", worker, "sub-worker"); +}, "postMessaging to a dedicated sub-worker allows them to see each others' modifications"); + +test(() => { + assert_true(self.crossOriginIsolated); +}, "Bonus: self.crossOriginIsolated"); + +done(); diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js.headers new file mode 100644 index 0000000000..6604450991 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js.headers @@ -0,0 +1 @@ +Cross-Origin-Embedder-Policy: require-corp diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/serviceworker-failure.js b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/serviceworker-failure.js new file mode 100644 index 0000000000..4e8fba636c --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/serviceworker-failure.js @@ -0,0 +1,33 @@ +"use strict"; +self.importScripts("/resources/testharness.js"); + +let state = "start in worker"; + +self.onmessage = e => { + if (e.data === "start in window") { + assert_equals(state, "start in worker"); + e.source.postMessage(state); + state = "we are expecting a messageerror due to the window sending us a SAB"; + } else if (e.data === "we are expecting a messageerror due to the worker sending us a SAB") { + assert_equals(state, "onmessageerror was received in worker"); + e.source.postMessage(new SharedArrayBuffer()); + state = "done in worker"; + } else { + e.source.postMessage(`worker onmessage was reached when in state "${state}" and data ${e.data}`); + } +}; + +self.onmessageerror = e => { + if (state === "we are expecting a messageerror due to the window sending us a SAB") { + assert_equals(e.constructor.name, "ExtendableMessageEvent", "type"); + assert_equals(e.data, null, "data"); + assert_equals(e.origin, self.origin, "origin"); + assert_not_equals(e.source, null, "source"); + assert_equals(e.ports.length, 0, "ports length"); + + state = "onmessageerror was received in worker"; + e.source.postMessage(state); + } else { + e.source.postMessage(`worker onmessageerror was reached when in state "${state}" and data ${e.data}`); + } +}; diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/serviceworker-failure.js.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/serviceworker-failure.js.headers new file mode 100644 index 0000000000..6604450991 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/serviceworker-failure.js.headers @@ -0,0 +1 @@ +Cross-Origin-Embedder-Policy: require-corp diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/sharedworker-failure.js b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/sharedworker-failure.js new file mode 100644 index 0000000000..8472318abd --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/sharedworker-failure.js @@ -0,0 +1,18 @@ +let state = "send-sw-failure" +onconnect = initialE => { + let port = initialE.source; + port.postMessage(state) + port.onmessage = e => { + if(state === "" && e.data === "send-window-failure") { + port.postMessage(new SharedArrayBuffer()) + } else { + port.postMessage("failure") + } + } + port.onmessageerror = e => { + if(state === "send-sw-failure") { + port.postMessage("send-sw-failure-success") + state = "" + } + } +} diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/sharedworker-failure.js.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/sharedworker-failure.js.headers new file mode 100644 index 0000000000..6604450991 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/sharedworker-failure.js.headers @@ -0,0 +1 @@ +Cross-Origin-Embedder-Policy: require-corp diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/test-incrementer.js b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/test-incrementer.js new file mode 100644 index 0000000000..9c3fb813ae --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/test-incrementer.js @@ -0,0 +1,80 @@ +"use strict"; + +self.getViewValue = (view, index) => { + if(view instanceof DataView) { + return view.getInt8(index); + } + return view[index]; +}; + +self.setViewValue = (view, index, value) => { + if(view instanceof DataView) { + view.setInt8(index, value); + } else { + view[index] = value; + } +}; + +self.maybeBigInt = (view, value) => { + if (view.constructor.name === "BigInt64Array" || view.constructor.name === "BigUint64Array") { + return BigInt(value); + } + return value; +}; + +self.testSharingViaIncrementerScript = (t, whereToListen, whereToListenLabel, whereToSend, whereToSendLabel, origin, type = "Int32Array") => { + return new Promise(resolve => { + const sab = new SharedArrayBuffer(8); + const view = new self[type](sab); + setViewValue(view, 0, maybeBigInt(view, 1)); + + whereToListen.onmessage = t.step_func(({ data }) => { + switch (data.message) { + case "initial payload received": { + assert_equals(data.value, maybeBigInt(view, 1), `The ${whereToSendLabel} must see the same value in the SharedArrayBuffer`); + break; + } + + case "changed to 2": { + assert_equals(getViewValue(view, 0), maybeBigInt(view, 2), `The ${whereToListenLabel} must see changes made in the ${whereToSendLabel}`); + + setViewValue(view, 0, maybeBigInt(view, 3)); + whereToSend.postMessage({ message: "changed to 3" }, origin); + + break; + } + + case "changed to 3 received": { + assert_equals(data.value, maybeBigInt(view, 3), `The ${whereToSendLabel} must see changes made in the ${whereToListenLabel}`); + resolve(); + break; + } + } + }); + + whereToSend.postMessage({ message: "initial payload", view }, origin); + }); +}; + +self.setupDestinationIncrementer = (whereToListen, whereToSendBackTo, origin) => { + let view; + whereToListen.onmessage = ({ data }) => { + switch (data.message) { + case "initial payload": { + view = data.view; + whereToSendBackTo.postMessage({ message: "initial payload received", value: getViewValue(view, 0) }, origin); + + setViewValue(view, 0, maybeBigInt(view, 2)); + whereToSendBackTo.postMessage({ message: "changed to 2" }, origin); + + break; + } + + case "changed to 3": { + whereToSendBackTo.postMessage({ message: "changed to 3 received", value: getViewValue(view, 0) }, origin); + + break; + } + } + }; +}; diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/test-sab.js b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/test-sab.js new file mode 100644 index 0000000000..6d6efda00d --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/test-sab.js @@ -0,0 +1,15 @@ +"use strict"; + +self.assertSABsHaveSameBackingBlock = (originalSAB, clonedSAB) => { + const originalView = new Uint8Array(originalSAB); + const clonedView = new Uint8Array(clonedSAB); + + assert_not_equals(originalSAB, clonedSAB, "the clone must not be the same object"); + + assert_equals(originalView[0], 0, "originalView[0] starts 0"); + assert_equals(clonedView[0], 0, "clonedView[0] starts 0"); + + originalView[0] = 5; + assert_equals(originalView[0], 5, "originalView[0] ends up 5"); + assert_equals(clonedView[0], 5, "clonedView[0] ends up 5"); +}; diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-history.https.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-history.https.html new file mode 100644 index 0000000000..28859f17cb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-history.https.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>SharedArrayBuffers cloning via history's methods invoking StructuredSerializeForStorage</title> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#structuredserializeforstorage"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-history-pushstate"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-history-replacestate"> +<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script> +"use strict"; + +for (const method of ["pushState", "replaceState"]) { + test(() => { + assert_throws_dom("DataCloneError", () => { + history[method](new SharedArrayBuffer(), "dummy title"); + }); + }, `history.${method}(): simple case`); + + test(() => { + let getter1Called = false; + let getter2Called = false; + assert_throws_dom("DataCloneError", () => { + history[method]([ + { get x() { getter1Called = true; return 5; } }, + new SharedArrayBuffer(), + { get x() { getter2Called = true; return 5; } } + ], "dummy title"); + }); + + assert_true(getter1Called, "The getter before the SAB must have been called"); + assert_false(getter2Called, "The getter after the SAB must not have been called"); + }, `history.${method}(): is interleaved correctly`); +} +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-history.https.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-history.https.html.headers new file mode 100644 index 0000000000..63b60e490f --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-history.https.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-idb.any.js b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-idb.any.js new file mode 100644 index 0000000000..e317b150cc --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-idb.any.js @@ -0,0 +1,44 @@ +// META: script=/IndexedDB/resources/support.js +"use strict"; + +async_test(t => { + const openReq = createdb(t); + + openReq.onupgradeneeded = e => { + const db = e.target.result; + const store = db.createObjectStore("store", { keyPath: "key" }); + // See https://github.com/whatwg/html/issues/5380 for why not `new SharedArrayBuffer()` + const sab = new WebAssembly.Memory({ shared:true, initial:1, maximum:1 }).buffer; + + assert_throws_dom("DataCloneError", () => { + store.put({ key: 1, property: sab }); + }); + t.done(); + }; +}, "SharedArrayBuffer cloning via IndexedDB: basic case"); + +async_test(t => { + const openReq = createdb(t); + + openReq.onupgradeneeded = e => { + const db = e.target.result; + const store = db.createObjectStore("store", { keyPath: "key" }); + // See https://github.com/whatwg/html/issues/5380 for why not `new SharedArrayBuffer()` + const sab = new WebAssembly.Memory({ shared:true, initial:1, maximum:1 }).buffer; + + let getter1Called = false; + let getter2Called = false; + + assert_throws_dom("DataCloneError", () => { + store.put({ key: 1, property: [ + { get x() { getter1Called = true; return 5; } }, + sab, + { get x() { getter2Called = true; return 5; } } + ]}); + }); + + assert_true(getter1Called, "The getter before the SAB must have been called"); + assert_false(getter2Called, "The getter after the SAB must not have been called"); + t.done(); + }; +}, "SharedArrayBuffer cloning via the IndexedDB: is interleaved correctly"); diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-notifications-api.any.js b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-notifications-api.any.js new file mode 100644 index 0000000000..4c1c1fdabb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-notifications-api.any.js @@ -0,0 +1,28 @@ +"use strict"; + +test(() => { + assert_throws_dom("DataCloneError", () => { + // See https://github.com/whatwg/html/issues/5380 for why not `new SharedArrayBuffer()` + const sab = new WebAssembly.Memory({ shared:true, initial:1, maximum:1 }).buffer; + new Notification("Bob: Hi", { data: sab }); + }) +}, "SharedArrayBuffer cloning via the Notifications API's data member: basic case"); + +test(() => { + // See https://github.com/whatwg/html/issues/5380 for why not `new SharedArrayBuffer()` + const sab = new WebAssembly.Memory({ shared:true, initial:1, maximum:1 }).buffer; + + let getter1Called = false; + let getter2Called = false; + + assert_throws_dom("DataCloneError", () => { + new Notification("Bob: Hi", { data: [ + { get x() { getter1Called = true; return 5; } }, + sab, + { get x() { getter2Called = true; return 5; } } + ]}); + }); + + assert_true(getter1Called, "The getter before the SAB must have been called"); + assert_false(getter2Called, "The getter after the SAB must not have been called"); +}, "SharedArrayBuffer cloning via the Notifications API's data member: is interleaved correctly"); diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-failure.https.sub.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-failure.https.sub.html new file mode 100644 index 0000000000..6fa196e094 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-failure.https.sub.html @@ -0,0 +1,49 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Structured cloning of SharedArrayBuffers into same-origin-domain windows</title> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#structuredserialize"> +<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<body> +<script> +"use strict"; +document.domain = "{{host}}"; + +async_test(t => { + const iframe = document.createElement("iframe"); + t.add_cleanup(() => iframe.remove()); + iframe.src = "//{{domains[www1]}}:{{location[port]}}/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/iframe-domain-failure.sub.html"; + let domain; + let childCrossOriginIsolated; + window.onmessage = t.step_func((e) => { + if (e.data.name === "domain") { + domain = e.data.value; + return; + } + if (e.data.name === "crossOriginIsolated") { + childCrossOriginIsolated = e.data.value; + return; + } + if (e.data.name === "hasSharedArrayBuffer") { + const hasSharedArrayBuffer = e.data.value; + + // document.domain mutation is no-op because the surrounding agent + // cluster's cross-origin isolated is true. + assert_equals(domain, "{{domains[www1]}}"); + + // crossOriginIsolated is false in the nested frame because the frame is + // cross-origin and hence the cross-origin isolated capability is false. + // We use assert_equals instead of assert_false here to see if + // `childCrossOriginIsolated` is set. + assert_equals(childCrossOriginIsolated, false); + + assert_false(hasSharedArrayBuffer); + t.done(); + return; + } + assert_unreached("Got a message event, expected a messageerror event"); + }); + document.body.append(iframe); +}, "SharedArrayBuffer and a same-origin-domain (but not same-origin) iframe"); +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-failure.https.sub.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-failure.https.sub.html.headers new file mode 100644 index 0000000000..63b60e490f --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-failure.https.sub.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-failure.https.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-failure.https.html new file mode 100644 index 0000000000..203a9f637f --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-failure.https.html @@ -0,0 +1,15 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<div id=log></div> +<script> +async_test(t => { + const frame = document.createElement("iframe"); + t.add_cleanup(() => frame.remove()); + frame.src = get_host_info().HTTPS_NOTSAMESITE_ORIGIN + new URL("resources/iframe-failure.html", location).pathname; + window.onmessage = t.unreached_func("Got a message event, expected a messageerror event"); + window.onmessageerror = t.step_func_done(); + document.body.append(frame); +}, "SharedArrayBuffer and a cross-site <iframe>"); +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-failure.https.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-failure.https.html.headers new file mode 100644 index 0000000000..63b60e490f --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-failure.https.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel.https.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel.https.html new file mode 100644 index 0000000000..acef65cbdf --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel.https.html @@ -0,0 +1,80 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Structured cloning of SharedArrayBuffers into windows using MessageChannel</title> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#structuredserialize"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/test-incrementer.js"></script> +<script src="/common/get-host-info.sub.js"></script> + +<div id="log"></div> + +<script> +promise_test(t => { + return new Promise(resolve => { + const iframe = document.createElement("iframe"); + window.onmessage = t.step_func((message) => { + // data will be a MessagePort + resolve(testSharingViaIncrementerScript(t, message.data, "window", message.data, "iframe")); + }); + iframe.src = "resources/incrementer-iframe-messagechannel.html"; + document.body.appendChild(iframe); + }); +}, `postMessaging to a same-origin iframe via MessageChannel allows them to see each others' modifications`); + +promise_test(t => { + return new Promise(resolve => { + const iframe = document.createElement("iframe"); + window.onmessage = t.step_func((message) => { + // data will be a MessagePort + message.data.postMessage(new SharedArrayBuffer(10)); + message.data.onmessage = t.step_func(message => { + assert_equals(message.data, "messageerror event received"); + resolve(); + }); + }); + iframe.src = get_host_info().HTTPS_REMOTE_ORIGIN + new URL("resources/iframe-messagechannel-site-failure.html", window.location).pathname; + document.body.appendChild(iframe); + }); +}, "postMessaging to a same-site iframe via MessageChannel should fail"); + +promise_test(t => { + return new Promise(resolve => { + const iframe = document.createElement("iframe"); + window.onmessage = t.step_func(message => { + // data will be a MessagePort + message.data.postMessage(new SharedArrayBuffer(10)); + message.data.onmessage = t.step_func(message => { + assert_equals(message.data, "messageerror event received"); + resolve(); + }); + }); + iframe.src = get_host_info().HTTPS_NOTSAMESITE_ORIGIN + new URL("resources/iframe-messagechannel-failure.html", window.location).pathname; + document.body.append(iframe); + }); +}, "postMessaging to a cross-site iframe via MessageChannel should fail"); + +promise_test(t => { + return new Promise(resolve => { + const iframe = document.createElement("iframe"); + let port = null; + window.onmessage = t.step_func(message => { + if (message.data.state === "port1") { + port = message.data.data; + port.postMessage(new SharedArrayBuffer(10)); + message.source.postMessage("send port2", "*"); + } else if (message.data.state === "port2") { + // Note that onmessage calls start() + message.data.data.onmessage = t.step_func(message => { + assert_true(message.data instanceof SharedArrayBuffer); + assert_equals(message.data.byteLength, 10); + resolve(); + }); + message.data.data.onmessageerror = t.unreached_func(); + } + }); + iframe.src = get_host_info().HTTPS_NOTSAMESITE_ORIGIN + new URL("resources/iframe-messagechannel-complex.html", window.location).pathname; + document.body.append(iframe); + }); +}, "postMessaging with a MessageChannel that's been cross-site should succeed"); +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel.https.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel.https.html.headers new file mode 100644 index 0000000000..63b60e490f --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel.https.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-messagechannel-success.https.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-messagechannel-success.https.html new file mode 100644 index 0000000000..cd67e5b2c9 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-messagechannel-success.https.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Structured cloning of SharedArrayBuffers using MessageChannel</title> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#structuredserialize"> +<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/test-incrementer.js"></script> + +<div id="log"></div> + +<script> +"use strict"; + +promise_test(t => { + const worker = new Worker("resources/incrementer-worker-with-channel.js"); + const channel = new MessageChannel(); + worker.postMessage(channel.port2, [channel.port2]); + + return testSharingViaIncrementerScript(t, channel.port1, "window", channel.port1, "worker"); +}, "postMessaging to a dedicated worker via MessageChannel allows them to see each others' modifications"); +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-messagechannel-success.https.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-messagechannel-success.https.html.headers new file mode 100644 index 0000000000..63b60e490f --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-messagechannel-success.https.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-serviceworker-failure.https.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-serviceworker-failure.https.html new file mode 100644 index 0000000000..373359de85 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-serviceworker-failure.https.html @@ -0,0 +1,56 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>SharedArrayBuffer cannot cross agent clusters, service worker edition</title> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#structuredserialize"> +<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> + +<script> +"use strict"; +promise_test(t => { + const scope = "resources/blank.html"; + return service_worker_unregister_and_register(t, "resources/serviceworker-failure.js", scope) + .then(reg => { + t.add_cleanup(() => service_worker_unregister(t, scope)); + return wait_for_state(t, reg.installing, "activated"); + }) + .then(() => with_iframe(scope)) + .then(iframe => { + t.add_cleanup(() => iframe.remove()); + const sw = iframe.contentWindow.navigator.serviceWorker; + let state = "start in window"; + + return new Promise(resolve => { + sw.onmessage = t.step_func(e => { + if (e.data === "start in worker") { + assert_equals(state, "start in window"); + sw.controller.postMessage(new SharedArrayBuffer()); + state = "we are expecting confirmation of an onmessageerror in the worker"; + } else if (e.data === "onmessageerror was received in worker") { + assert_equals(state, "we are expecting confirmation of an onmessageerror in the worker"); + state = "we are expecting a messageerror due to the worker sending us a SAB"; + sw.controller.postMessage(state); + } else { + assert_unreached("Got an unexpected message from the service worker: " + e.data); + } + }); + + sw.onmessageerror = t.step_func(e => { + assert_equals(state, "we are expecting a messageerror due to the worker sending us a SAB"); + + assert_equals(e.data, null, "data"); + assert_equals(e.origin, self.origin, "origin"); + assert_not_equals(e.source, null, "source"); + assert_equals(e.ports.length, 0, "ports length"); + + state = "done in window"; + resolve(); + }); + + sw.controller.postMessage(state); + }); + }); +}); +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-serviceworker-failure.https.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-serviceworker-failure.https.html.headers new file mode 100644 index 0000000000..63b60e490f --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-serviceworker-failure.https.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-sharedworker-failure.https.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-sharedworker-failure.https.html new file mode 100644 index 0000000000..023cb5acde --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-sharedworker-failure.https.html @@ -0,0 +1,31 @@ +<!doctype html> +<title>SharedArrayBuffer cannot cross agent clusters, shared worker edition</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script> +async_test(t => { + const sw = new SharedWorker("resources/sharedworker-failure.js") + let state = "" + sw.port.onmessage = t.step_func(e => { + if(e.data === "send-sw-failure") { + sw.port.postMessage(new SharedArrayBuffer()) + } else if(e.data === "send-sw-failure-success") { + state = "send-window-failure" + sw.port.postMessage(state) + } else { + assert_unreached() + } + }) + sw.port.onmessageerror = t.step_func(e => { + if(state === "send-window-failure") { + assert_equals(e.data, null, "data") + assert_equals(e.origin, "", "origin") + assert_equals(e.source, null, "source") + assert_equals(e.ports.length, 0, "ports length") + t.done() + } else { + assert_unreached() + } + }) +}) +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-sharedworker-failure.https.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-sharedworker-failure.https.html.headers new file mode 100644 index 0000000000..63b60e490f --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-sharedworker-failure.https.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-simple-success.https.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-simple-success.https.html new file mode 100644 index 0000000000..c9b41d0a0d --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-simple-success.https.html @@ -0,0 +1,72 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Structured cloning of SharedArrayBuffers: simple success cases that don't need dedicated files</title> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#structuredserialize"> +<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/test-incrementer.js"></script> + +<div id="log"></div> + +<script> +"use strict"; + +[ + "DataView", + "Int8Array", + "Uint8Array", + "Uint8ClampedArray", + "Int16Array", + "Uint16Array", + "Int32Array", + "Uint32Array", + "BigInt64Array", + "BigUint64Array", + "Float32Array", + "Float64Array" +].forEach(type => { + promise_test(t => { + const worker = new Worker("resources/incrementer-worker.js"); + + return testSharingViaIncrementerScript(t, worker, "window", worker, "worker", undefined, type); + }, "postMessaging to a dedicated worker allows them to see each others' modifications with " + type); +}); + +promise_test(t => { + return new Promise(resolve => { + const iframe = document.createElement("iframe"); + iframe.onload = t.step_func(() => { + resolve(testSharingViaIncrementerScript(t, window, "window", iframe.contentWindow, "iframe", "*")); + }); + iframe.src = "resources/incrementer-iframe.html"; + document.body.appendChild(iframe); + }); +}, "postMessaging to a same-origin iframe allows them to see each others' modifications"); + +promise_test(t => { + return new Promise(resolve => { + const iframe = document.createElement("iframe"); + iframe.onload = t.step_func(() => { + const level1 = iframe.contentWindow; + const level2 = level1.frames[0]; + const level3 = level2.frames[0]; + const targetWindow = level3.frames[0]; + resolve(testSharingViaIncrementerScript(t, window, "window", targetWindow, "nested iframe", "*")); + }); + iframe.src = "resources/nested-iframe-1.html"; + document.body.appendChild(iframe); + }); +}, "postMessaging to a same-origin deeply-nested iframe allows them to see each others' modifications"); + +promise_test(t => { + return new Promise(resolve => { + const w = window.open("resources/incrementer-popup.html"); + w.onload = t.step_func(() => { + resolve(testSharingViaIncrementerScript(t, window, "window", w, "popup window", "*").then(() => { + w.close(); + })); + }); + }); +}, "postMessaging to a same-origin opened window allows them to see each others' modifications"); +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-simple-success.https.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-simple-success.https.html.headers new file mode 100644 index 0000000000..63b60e490f --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-simple-success.https.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-extra.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-extra.html new file mode 100644 index 0000000000..5ff10cbc10 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-extra.html @@ -0,0 +1,46 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Structured cloning of Error objects: extra tests</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<!-- Most tests are in the general framework in structuredclone_0.html. + This contains specialty tests that don't fit into that framework. --> + +<body> + +<script> +"use strict"; +test(t => { + const exceptionToThrow = new Error("throw me!"); + + const badError = new Error(); + Object.defineProperty(badError, "name", { get() { throw exceptionToThrow; } }); + + const worker = new Worker("./resources/echo-worker.js"); + t.add_cleanup(() => worker.terminate()); + + assert_throws_exactly(exceptionToThrow, () => { + worker.postMessage(badError); + }); +}, "Throwing name getter fails serialization"); + +// https://bugs.chromium.org/p/chromium/issues/detail?id=1030086 +// https://github.com/whatwg/html/pull/5150 +async_test(t => { + window.onmessage = t.step_func_done(e => { + assert_equals(e.data.name, "TypeError"); + }); + + const iframe = document.createElement("iframe"); + iframe.onload = () => { + if (iframe.contentWindow.location === "about:blank") { + return; + } + + iframe.contentWindow.doIt(); + }; + iframe.src = "resources/post-parent-type-error.html"; + document.body.append(iframe); +}, "Errors sent across realms should preserve their type"); +</script> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js new file mode 100644 index 0000000000..cbc6a73d51 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js @@ -0,0 +1,106 @@ +// META: script=/common/utils.js + +// .stack properties on errors are unspecified, but are present in most +// browsers, most of the time. https://github.com/tc39/proposal-error-stacks/ tracks standardizing them. +// Tests will pass automatically if the .stack property isn't present. + +stackTests(() => { + return new Error('some message'); +}, 'page-created Error'); + +stackTests(() => { + return new DOMException('InvalidStateError', 'some message'); +}, 'page-created DOMException'); + +stackTests(() => { + try { + Object.defineProperty(); + } catch (e) { + return e; + } +}, 'JS-engine-created TypeError'); + +stackTests(() => { + try { + HTMLParagraphElement.prototype.align; + } catch (e) { + return e; + } +}, 'web API-created TypeError'); + +stackTests(() => { + try { + document.createElement(''); + } catch (e) { + return e; + } +}, 'web API-created DOMException'); + +function stackTests(errorFactory, description) { + test(t => { + const error = errorFactory(); + const originalStack = error.stack; + + if (!originalStack) { + return; + } + + const clonedError = structuredClone(error); + assert_equals(clonedError.stack, originalStack); + }, description + ' (structuredClone())'); + + async_test(t => { + const error = errorFactory(); + const originalStack = error.stack; + + if (!originalStack) { + t.done(); + return; + } + + const worker = new Worker('resources/echo-worker.js'); + worker.onmessage = t.step_func_done(e => { + assert_equals(e.data.stack, originalStack); + }); + + worker.postMessage(error); + }, description + ' (worker)'); + + let iframeTest = (t, url) => { + const thisTestId = token(); + + const error = errorFactory(); + const originalStack = error.stack; + + if (!originalStack) { + t.done(); + return; + } + + const iframe = document.createElement('iframe'); + window.addEventListener('message', t.step_func(e => { + if (e.data.testId === thisTestId) { + assert_equals(e.data.error.stack, originalStack); + t.done(); + } + })); + + iframe.onload = t.step_func(() => { + iframe.contentWindow.postMessage({ error, testId: thisTestId }, "*"); + }); + + iframe.src = url; + document.body.append(iframe); + } + + async_test(t => { + const crossSiteURL = new URL('resources/echo-iframe.html', location.href); + crossSiteURL.hostname = '{{hosts[alt][www1]}}'; + iframeTest(t, crossSiteURL); + }, description + ' (cross-site iframe)'); + + async_test(t => { + const sameOriginURL = new URL('resources/echo-iframe.html', location.href); + iframeTest(t, sameOriginURL); + }, description + ' (same-origin iframe)') +} diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/structuredclone_0.html b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/structuredclone_0.html new file mode 100644 index 0000000000..c8a6d38393 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/structuredclone_0.html @@ -0,0 +1,637 @@ +<!doctype html> +<html> + <head> + <meta content="text/html; charset=utf-8" http-equiv="content-type" /> + <title>2.8 Common DOM interfaces - Structured Clone Algorithm </title> + <link rel="help" href="http://www.w3.org/TR/html5/common-dom-interfaces.html#safe-passing-of-structured-data" /> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> +</head> +<body> + <div id="log"></div> + <iframe></iframe> <!-- used for grabbing an URIError from another realm --> + +<script type="text/javascript"> + var worker; + var testCollection; + setup(function() + { + //the worker is used for each test in sequence + //worker's callback will be set for each test + //worker's internal onmessage echoes the data back to this thread through postMessage + worker = new Worker("./resources/echo-worker.js"); + testCollection = [ + function() { + var t = async_test("Primitive string is cloned"); + t.id = 0; + worker.onmessage = t.step_func(function(e) {assert_equals("primitive string", e.data, "\"primitive string\" === event.data"); t.done(); }); + t.step(function() { worker.postMessage("primitive string");}); + }, + function() { + var t = async_test("Primitive integer is cloned"); + t.id = 1; + worker.onmessage = t.step_func(function(e) {assert_equals(2000, e.data, "2000 === event.data"); t.done(); }); + t.step(function() { worker.postMessage(2000);}); + }, + function() { + var t = async_test("Primitive floating point is cloned"); + t.id = 2; + worker.onmessage = t.step_func(function(e) {assert_equals(111.456, e.data, "111.456 === event.data"); t.done(); }); + t.step(function() { worker.postMessage(111.456);}); + }, + function() { + var t = async_test("Primitive floating point (negative) is cloned"); + t.id = 3; + worker.onmessage = t.step_func(function(e) {assert_equals(-111.456, e.data, "-111.456 === event.data"); t.done(); }); + t.step(function() { worker.postMessage(-111.456);}); + }, + function() { + var t = async_test("Primitive number (hex) is cloned"); + t.id = 4; + worker.onmessage = t.step_func(function(e) {assert_equals(0xAB25, e.data, "0xAB25 === event.data"); t.done(); }); + t.step(function() { worker.postMessage(0xAB25);}); + }, + function() { + var t = async_test("Primitive number (scientific) is cloned"); + t.id = 5; + worker.onmessage = t.step_func(function(e) {assert_equals(15e2, e.data, "15e2 === event.data"); t.done(); }); + t.step(function() { worker.postMessage(15e2);}); + }, + function() { + var t = async_test("Primitive boolean is cloned"); + t.id = 6; + worker.onmessage = t.step_func(function(e) {assert_equals(false, e.data, "false === event.data"); t.done(); }); + t.step(function() { worker.postMessage(false);}); + }, + function() { + var t = async_test("Instance of Boolean is cloned"); + t.id = 7; + var obj; + t.step(function() {obj = new Boolean(false);}); + worker.onmessage = t.step_func(function(e) { + assert_equals(obj.constructor, e.data.constructor, "Boolean === event.data.constructor"); + assert_equals(obj.valueOf(), e.data.valueOf(), "(new Boolean(false)).valueof() === event.data.valueOf()"); + t.done(); + }); + t.step(function() { worker.postMessage(obj);}); + },function() { + var t = async_test("Instance of Number is cloned"); + t.id = 8; + var obj; + t.step(function() {obj = new Number(2000);}); + worker.onmessage = t.step_func(function(e) { + assert_equals(obj.constructor, e.data.constructor, "Number === event.data.constructor"); + assert_equals(obj.valueOf(), e.data.valueOf(), "(new Number(2000)).valueof() === event.data.valueOf()"); + t.done(); + }); + t.step(function() { worker.postMessage(obj);}); + }, + function() { + var t = async_test("Instance of String is cloned"); + t.id = 9; + var obj; + t.step(function() { obj = new String("String Object");}); + worker.onmessage = t.step_func(function(e) { + assert_equals(obj.constructor, e.data.constructor, "String === event.data.constructor"); + assert_equals(obj.valueOf(), e.data.valueOf(), "(new String(\"String Object\")).valueof() === event.data.valueOf()"); + t.done(); + }); + t.step(function() { worker.postMessage(obj);}); + }, + function() { + var t = async_test("Instance of Date is cloned"); + t.id = 10; + var obj; + t.step(function() { obj= new Date(2011,1,1);}); + worker.onmessage = t.step_func(function(e) { + assert_equals(obj.constructor, e.data.constructor, "Date === event.data.constructor"); + assert_equals(obj.valueOf(), e.data.valueOf(), "(new Date(2011,1,1)).valueof() === event.data.valueOf()"); + t.done(); + }); + t.step(function() { worker.postMessage(obj);}); + }, + function() { + var t = async_test("Instance of RegExp is cloned"); + t.id = 11; + var obj; + t.step(function() {obj = new RegExp("w3+c","g","i");}); + worker.onmessage = t.step_func(function(e) { + assert_equals(obj.constructor, e.data.constructor, "RegExp === event.data.constructor"); + assert_equals(obj.source, e.data.source, "canon.source === event.data.source"); + assert_equals(obj.multiline, e.data.multiline, "canon.multiline === event.data.multiline"); + assert_equals(obj.global, e.data.global, "canon.global === event.data.global"); + assert_equals(obj.ignoreCase, e.data.ignoreCase, "canon.ignoreCase === event.data.ignoreCase"); + t.done(); + }); + t.step(function() { worker.postMessage(obj);}); + }, + function() { + var t = async_test("Value 'null' is cloned"); + t.id = 12; + worker.onmessage = t.step_func(function(e) {assert_equals(null, e.data, "null === event.data"); t.done(); }); + t.step(function() { worker.postMessage(null);}); + }, + function() { + var t = async_test("Value 'undefined' is cloned"); + t.id = 13; + worker.onmessage = t.step_func(function(e) {assert_equals(undefined, e.data, "undefined === event.data"); t.done(); }); + t.step(function() { worker.postMessage(undefined);}); + }, + function() { + var t = async_test("Object properties are cloned"); + t.id = 14; + var obj; + t.step(function() { + obj= {}; + obj.a = "test"; + obj.b = 2; + obj["child"] = 3; + }); + worker.onmessage = t.step_func(function(e) { + assert_equals(obj.constructor, e.data.constructor, "canon.constructor === event.data.constructor"); + assert_equals(obj.a, e.data.a, "canon.a === event.data.a"); + assert_equals(obj.b, e.data.b, "canon.b === event.data.b"); + assert_equals(obj.child, e.data.child, "canon.child === e.data.child"); + t.done(); + }); + t.step(function() { worker.postMessage(obj);}); + }, + function() { + var t = async_test("Prototype chains are not walked."); + t.id = 15; + function Custom() { + this.a = "hello"; + } + + var obj; + t.step(function() { + Object.defineProperty(Custom.prototype, "b", { enumerable: true, value: 100 }); + obj = new Custom(); + }); + worker.onmessage = t.step_func(function(e) { + assert_not_equals(obj.constructor, e.data.constructor, "canon.constructor !== event.data.constructor"); + assert_equals(Object, e.data.constructor, "Object === e.data.constructor"); + assert_equals(obj.a, e.data.a, "canon.a === e.data.a"); + assert_equals(undefined, e.data.b, "undefined === e.data.b"); + t.done(); + }); + t.step(function() { worker.postMessage(obj);}); + }, + function() { + var t = async_test("Property descriptors of Objects are not cloned"); + t.id = 16; + var obj; + t.step(function() { + obj = {}; + Object.defineProperty(obj, "a", { enumerable: true, writable: false, value: 100 }); + }); + worker.onmessage = t.step_func(function(e) { + var des = Object.getOwnPropertyDescriptor(e.data, "a"); + assert_equals(obj.constructor, e.data.constructor, "canon.constructor === event.data.constructor"); + assert_true(des.writable, "Descriptor is writable"); + t.done(); + }); + t.step(function() { worker.postMessage(obj);}); + }, + function() { + var t = async_test("Cycles are preserved in Objects"); + t.id = 17; + var obj; + t.step(function() { + obj = {}; + obj.a = obj; + }); + worker.onmessage = t.step_func(function(e) { + assert_equals(obj.constructor, e.data.constructor, "canon.constructor === event.data.constructor"); + assert_equals(e.data, e.data.a, "cycle is preserved"); + t.done(); + }); + t.step(function() { worker.postMessage(obj);}); + }, + function() { + var t = async_test("Identity of duplicates is preserved"); + t.id = 18; + var ref; + var obj; + t.step(function() { + ref = {}; + ref.called = 0; + Object.defineProperty(ref, "child", {get: function(){this.called++;}, enumerable: true}); + + obj = {a:ref, b:ref}; + }); + worker.onmessage = t.step_func(function(e) { + assert_equals(obj.constructor, e.data.constructor, "canon.constructor === event.data.constructor"); + assert_equals(e.data.b.called, 0, "e.data.b.called === 0"); + t.done(); + }); + t.step(function() { worker.postMessage(obj);}); + }, + function() { + var t = async_test("Property order is preserved"); + t.id = 19; + var obj; + t.step(function() { + obj = { "a": "hello", "b": "w3c", "c": "and world" }; + obj["a"] = "named1"; + }); + worker.onmessage = t.step_func(function(e) { + assert_equals(obj.constructor, e.data.constructor, "canon.constructor === event.data.constructor"); + var canonNames = Object.getOwnPropertyNames(obj); + var testNames = Object.getOwnPropertyNames(e.data); + for (var i in canonNames) { + assert_equals(canonNames[i], testNames[i], "canonProperty["+i+"] === dataProperty["+i+"]"); + } + t.done(); + }); + t.step(function() { worker.postMessage(obj);}); + }, + function() { + var t = async_test("Enumerable properties of Arrays are cloned"); + t.id = 20; + var obj; + t.step(function() { + obj = [0,1]; + obj["a"] = "named1"; + }); + worker.onmessage = t.step_func(function(e) { + assert_equals(obj.constructor, e.data.constructor, "canon.constructor === event.data.constructor"); + assert_equals(e.data["a"], "named1", "e.data[\"a\"] === \"named1\""); + assert_equals(e.data[0], 0, "e.data[0] === 0"); + assert_equals(e.data[1], 1, "e.data[1] === 1"); + t.done(); + }); + t.step(function() { worker.postMessage(obj);}); + }, + function() { + var t = async_test("Property descriptors of Arrays are not cloned"); + t.id = 21; + var obj; + t.step(function() { + obj = [0, 1]; + Object.defineProperty(obj, "2", { enumerable: true, writable: false, value: 100 }); + }); + worker.onmessage = t.step_func(function(e) { + assert_equals(obj.constructor, e.data.constructor, "canon.constructor === event.data.constructor"); + assert_equals(e.data[0], 0, "e.data[0] === 0"); + assert_equals(e.data[1], 1, "e.data[1] === 1"); + var des = Object.getOwnPropertyDescriptor(e.data, "2"); + assert_true(des.writable, "Descriptor is writable"); + t.done(); + }); + t.step(function() { worker.postMessage(obj);}); + }, + function() { + var t = async_test("Cycles are preserved in Arrays"); + t.id = 22; + var obj; + t.step(function() { + obj = [0,1]; + obj[2] = obj; + }); + worker.onmessage = t.step_func(function(e) { + assert_equals(obj.constructor, e.data.constructor, "canon.constructor === event.data.constructor"); + assert_equals(e.data[0], 0, "e.data[0] === 0"); + assert_equals(e.data[1], 1, "e.data[1] === 1"); + assert_equals(e.data[2], e.data, "e.data[2] === e.data"); + t.done(); + }); + t.step(function() { worker.postMessage(obj);}); + }, + + function() { + var t = async_test("ImageData object can be cloned"); + t.id = 23; + var obj; + t.step(function() { + var canvas = document.createElement("canvas"); + canvas.width = 40; + canvas.height = 40; + var context = canvas.getContext('2d'); + obj = context.createImageData(40, 40); + assert_true(window.hasOwnProperty("ImageData"), "ImageData constructor must be present"); + assert_true(obj instanceof ImageData, "ImageData must be returned by .createImageData"); + }); + worker.onmessage = t.step_func(function(e) { + assert_equals(obj.constructor, e.data.constructor, "canon.constructor === event.data.constructor"); + assert_not_equals(obj, e.data, "cloned object should be a new instance of ImageData"); + assert_equals(obj.width, e.data.width, "canon.width === e.data.width"); + assert_equals(obj.height, e.data.height, "canon.height === e.data.height"); + assert_array_equals(obj.data, e.data.data, "data arrays are the same"); + t.done(); + }); + t.step(function() { worker.postMessage(obj);}); + }, + function() { + var t = async_test("ImageData expandos are not cloned"); + t.id = 24; + var obj; + t.step(function() { + var canvas = document.createElement("canvas"); + canvas.width = 40; + canvas.height = 40; + var context = canvas.getContext('2d'); + obj = context.createImageData(40, 40); + assert_true(window.hasOwnProperty("ImageData"), "ImageData constructor must be present"); + assert_true(obj instanceof ImageData, "ImageData must be returned by .createImageData"); + obj.foo = "bar"; + }); + worker.onmessage = t.step_func(function(e) { + assert_equals(obj.constructor, e.data.constructor, "canon.constructor === event.data.constructor"); + assert_not_equals(obj, e.data, "cloned object should be a new instance of ImageData"); + assert_equals(obj.width, e.data.width, "canon.width === e.data.width"); + assert_equals(obj.height, e.data.height, "canon.height === e.data.height"); + assert_array_equals(obj.data, e.data.data, "data arrays are the same"); + assert_equals(undefined, e.data.foo, "Expando is lost (undefined === e.data.foo)"); + t.done(); + }); + t.step(function() { worker.postMessage(obj);}); + }, + function() { + var t = async_test("Window objects cannot be cloned"); + t.id = 25; + worker.onmessage = function() {}; //no op because exception should be thrown. + t.step(function() { + assert_true(DOMException.hasOwnProperty('DATA_CLONE_ERR'), "DOMException.DATA_CLONE_ERR is present"); + assert_equals(DOMException.DATA_CLONE_ERR, 25, "DOMException.DATA_CLONE_ERR === 25"); + assert_throws_dom('DATA_CLONE_ERR', function() {worker.postMessage(window)}); + }); + t.done(); + }, + function() { + var t = async_test("Document objects cannot be cloned"); + t.id = 26; + worker.onmessage = function() {}; //no op because exception should be thrown. + t.step(function() { + assert_true(DOMException.hasOwnProperty('DATA_CLONE_ERR'), "DOMException.DATA_CLONE_ERR is present"); + assert_equals(DOMException.DATA_CLONE_ERR, 25, "DOMException.DATA_CLONE_ERR === 25"); + assert_throws_dom('DATA_CLONE_ERR', function() {worker.postMessage(document)}); + }); + t.done(); + }, + function() { + var t = async_test("Empty Error objects can be cloned"); + t.id = 27; + worker.onmessage = t.step_func_done(function(e) { + assert_equals(Object.getPrototypeOf(e.data), Error.prototype, "Checking prototype"); + assert_equals(e.data.constructor, Error, "Checking constructor"); + assert_equals(e.data.name, "Error", "Checking name"); + assert_false(e.data.hasOwnProperty("message"), "Checking message"); + assert_equals(e.data.foo, undefined, "Checking custom property"); + }); + t.step(function() { + const error = Error(); + assert_false(error.hasOwnProperty("message"), "Checking message on the source realm"); + worker.postMessage(error); + }); + }, + function() { + var t = async_test("Error objects can be cloned"); + t.id = 28; + worker.onmessage = t.step_func_done(function(e) { + assert_equals(Object.getPrototypeOf(e.data), Error.prototype, "Checking prototype"); + assert_equals(e.data.constructor, Error, "Checking constructor"); + assert_equals(e.data.name, "Error", "Checking name"); + assert_equals(e.data.message, "some message", "Checking message"); + assert_equals(e.data.foo, undefined, "Checking custom property"); + }); + t.step(function() { + const error = Error("some message"); + error.foo = "bar"; + worker.postMessage(error); + }); + }, + function() { + var t = async_test("EvalError objects can be cloned"); + t.id = 29; + worker.onmessage = t.step_func_done(function(e) { + assert_equals(Object.getPrototypeOf(e.data), EvalError.prototype, "Checking prototype"); + assert_equals(e.data.constructor, EvalError, "Checking constructor"); + assert_equals(e.data.name, "EvalError", "Checking name"); + assert_equals(e.data.message, "some message", "Checking message"); + assert_equals(e.data.foo, undefined, "Checking custom property"); + }); + t.step(function() { + const error = EvalError("some message"); + error.foo = "bar"; + worker.postMessage(error); + }); + }, + function() { + var t = async_test("RangeError objects can be cloned"); + t.id = 30; + worker.onmessage = t.step_func_done(function(e) { + assert_equals(Object.getPrototypeOf(e.data), RangeError.prototype, "Checking prototype"); + assert_equals(e.data.constructor, RangeError, "Checking constructor"); + assert_equals(e.data.name, "RangeError", "Checking name"); + assert_equals(e.data.message, "some message", "Checking message"); + assert_equals(e.data.foo, undefined, "Checking custom property"); + }); + t.step(function() { + const error = RangeError("some message"); + error.foo = "bar"; + worker.postMessage(error); + }); + }, + function() { + var t = async_test("ReferenceError objects can be cloned"); + t.id = 31; + worker.onmessage = t.step_func_done(function(e) { + assert_equals(Object.getPrototypeOf(e.data), ReferenceError.prototype, "Checking prototype"); + assert_equals(e.data.constructor, ReferenceError, "Checking constructor"); + assert_equals(e.data.name, "ReferenceError", "Checking name"); + assert_equals(e.data.message, "some message", "Checking message"); + assert_equals(e.data.foo, undefined, "Checking custom property"); + }); + t.step(function() { + const error = ReferenceError("some message"); + error.foo = "bar"; + worker.postMessage(error); + }); + }, + function() { + var t = async_test("SyntaxError objects can be cloned"); + t.id = 32; + worker.onmessage = t.step_func_done(function(e) { + assert_equals(Object.getPrototypeOf(e.data), SyntaxError.prototype, "Checking prototype"); + assert_equals(e.data.constructor, SyntaxError, "Checking constructor"); + assert_equals(e.data.name, "SyntaxError", "Checking name"); + assert_equals(e.data.message, "some message", "Checking message"); + assert_equals(e.data.foo, undefined, "Checking custom property"); + }); + t.step(function() { + const error = SyntaxError("some message"); + error.foo = "bar"; + worker.postMessage(error); + }); + }, + function() { + var t = async_test("TypeError objects can be cloned"); + t.id = 33; + worker.onmessage = t.step_func_done(function(e) { + assert_equals(Object.getPrototypeOf(e.data), TypeError.prototype, "Checking prototype"); + assert_equals(e.data.constructor, TypeError, "Checking constructor"); + assert_equals(e.data.name, "TypeError", "Checking name"); + assert_equals(e.data.message, "some message", "Checking message"); + assert_equals(e.data.foo, undefined, "Checking custom property"); + }); + t.step(function() { + const error = TypeError("some message"); + error.foo = "bar"; + worker.postMessage(error); + }); + }, + function() { + var t = async_test("URIError objects can be cloned"); + t.id = 34; + worker.onmessage = t.step_func_done(function(e) { + assert_equals(Object.getPrototypeOf(e.data), URIError.prototype, "Checking prototype"); + assert_equals(e.data.constructor, URIError, "Checking constructor"); + assert_equals(e.data.name, "URIError", "Checking name"); + assert_equals(e.data.message, "some message", "Checking message"); + assert_equals(e.data.foo, undefined, "Checking custom property"); + }); + t.step(function() { + const error = URIError("some message"); + error.foo = "bar"; + worker.postMessage(error); + }); + }, + function() { + var t = async_test("URIError objects from other realms are treated as URIError"); + t.id = 35; + worker.onmessage = t.step_func_done(function(e) { + assert_equals(Object.getPrototypeOf(e.data), URIError.prototype, "Checking prototype"); + assert_equals(e.data.constructor, URIError, "Checking constructor"); + assert_equals(e.data.name, "URIError", "Checking name"); + assert_equals(e.data.message, "some message", "Checking message"); + assert_equals(e.data.foo, undefined, "Checking custom property"); + }); + t.step(function() { + const error = frames[0].URIError("some message"); + assert_equals(Object.getPrototypeOf(error), frames[0].URIError.prototype, "Checking prototype before cloning"); + assert_equals(error.constructor, frames[0].URIError, "Checking constructor before cloning"); + assert_equals(error.name, "URIError", "Checking name before cloning"); + error.foo = "bar"; + worker.postMessage(error); + }); + }, + function() { + var t = async_test("Cloning a modified Error"); + t.id = 36; + worker.onmessage = t.step_func_done(function(e) { + assert_equals(Object.getPrototypeOf(e.data), TypeError.prototype, "Checking prototype"); + assert_equals(e.data.constructor, TypeError, "Checking constructor"); + assert_equals(e.data.name, "TypeError", "Checking name"); + assert_equals(e.data.message, "another message", "Checking message"); + assert_equals(e.data.foo, undefined, "Checking custom property"); + }); + t.step(function() { + const error = URIError("some message"); + Object.setPrototypeOf(error, SyntaxError.prototype); + error.message = {toString: () => "another message" } + error.constructor = RangeError; + error.name = "TypeError"; + error.foo = "bar"; + worker.postMessage(error); + }); + }, + function() { + var t = async_test("Error.message: getter is ignored when cloning"); + t.id = 37; + worker.onmessage = t.step_func_done(function(e) { + assert_equals(Object.getPrototypeOf(e.data), Error.prototype, "Checking prototype"); + assert_equals(e.data.constructor, Error, "Checking constructor"); + assert_equals(e.data.name, "Error", "Checking name"); + assert_false(e.data.hasOwnProperty("message"), "Checking message"); + assert_equals(e.data.foo, undefined, "Checking custom property"); + }); + t.step(function() { + const error = Error(); + Object.defineProperty(error, "message", { get: () => "hello" }); + assert_equals(error.message, "hello", "Checking message on the source realm"); + worker.postMessage(error); + }); + }, + function() { + var t = async_test("Error.message: undefined property is stringified"); + t.id = 38; + worker.onmessage = t.step_func_done(function(e) { + assert_equals(Object.getPrototypeOf(e.data), Error.prototype, "Checking prototype"); + assert_equals(e.data.constructor, Error, "Checking constructor"); + assert_equals(e.data.name, "Error", "Checking name"); + assert_equals(e.data.message, "undefined", "Checking message"); + assert_equals(e.data.foo, undefined, "Checking custom property"); + }); + t.step(function() { + const error = Error(); + error.message = undefined; + assert_equals(error.message, undefined, "Checking message on the source realm"); + worker.postMessage(error); + }); + }, + function() { + var t = async_test("DOMException objects can be cloned"); + t.id = 39; + worker.onmessage = t.step_func_done(function(e) { + assert_equals(Object.getPrototypeOf(e.data), DOMException.prototype, "Checking prototype"); + assert_equals(e.data.constructor, DOMException, "Checking constructor"); + assert_equals(e.data.name, "IndexSizeError", "Checking name"); + assert_equals(e.data.message, "some message", "Checking message"); + assert_equals(e.data.code, DOMException.INDEX_SIZE_ERR, "Checking code"); + assert_equals(e.data.foo, undefined, "Checking custom property"); + }); + t.step(function() { + const error = new DOMException("some message", "IndexSizeError"); + worker.postMessage(error); + }); + }, + function() { + var t = async_test("DOMException objects created by the UA can be cloned"); + t.id = 40; + worker.onmessage = t.step_func_done(function(e) { + assert_equals(Object.getPrototypeOf(e.data), DOMException.prototype, "Checking prototype"); + assert_equals(e.data.constructor, DOMException, "Checking constructor"); + assert_equals(e.data.code, DOMException.DATA_CLONE_ERR, "Checking code"); + assert_equals(e.data.name, "DataCloneError", "Checking name"); + }); + t.step(function() { + try { + worker.postMessage(window); + } catch (error) { + worker.postMessage(error); + return; + } + assert_unreached("Window must not be clonable"); + }); + }, + ]; + }, {explicit_done:true}); + + //Callback for result_callback + //queues the next test in the array testCollection + //serves to make test execution sequential from the async worker callbacks + //alternatively, we would have to create a worker for each test + function testFinished(test) { + if(test.id < testCollection.length - 1) { + //queue the function so that stack remains shallow + queue(testCollection[test.id+1]); + } else { + //when the last test has run, explicitly end test suite + done(); + } + } + function queue(func) { + step_timeout(func, 10); + } + + add_result_callback(testFinished); + //start the first test manually + queue(testCollection[0]); + + + + + </script> +</body> +</html> diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/transfer-errors.window.js b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/transfer-errors.window.js new file mode 100644 index 0000000000..b3ecd86b40 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/transfer-errors.window.js @@ -0,0 +1,47 @@ +function assert_transfer_error(transferList) { + assert_throws_dom("DataCloneError", () => self.postMessage({ get whatever() { throw new Error("You should not have gotten to this point") } }, "*", transferList)); +} + +test(() => { + [self, self.document, new Image()].forEach(val => { + assert_transfer_error([val]); + }); +}, "Cannot transfer all objects"); + +function transfer_tests(name, create) { + promise_test(async () => { + const transferable = await create(); + assert_transfer_error([transferable, transferable]); + }, `Cannot transfer the same ${name} twice`); + + promise_test(async () => { + const transferable = await create(); + self.postMessage(null, "*", [transferable]); + assert_throws_dom("DataCloneError", () => self.postMessage(null, "*", [transferable])); + }, `Serialize should make the ${name} detached, so it cannot be transferred again`); + + promise_test(async () => { + const transferable = await create(), + customError = new Error("hi"); + self.postMessage(null, "*", [transferable]); + assert_throws_exactly(customError, () => self.postMessage({ get whatever() { throw customError } }, "*", [transferable])); + }, `Serialize should throw before a detached ${name} is found`); + + promise_test(async () => { + const transferable = await create(); + let seen = false; + const message = { + get a() { + self.postMessage(null, '*', [transferable]); + seen = true; + } + }; + assert_throws_dom("DataCloneError", () => self.postMessage(message, "*", [transferable])); + assert_true(seen); + }, `Cannot transfer ${name} detached while the message was serialized`); +} + +transfer_tests("ArrayBuffer", () => new ArrayBuffer(1)); +transfer_tests("MessagePort", () => new MessageChannel().port1); +transfer_tests("ImageBitmap", () => self.createImageBitmap(document.createElement("canvas"))); +transfer_tests("OffscreenCanvas", () => new OffscreenCanvas(1, 1)); diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/window-postmessage.window.js b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/window-postmessage.window.js new file mode 100644 index 0000000000..2a46d790b8 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/window-postmessage.window.js @@ -0,0 +1,16 @@ +// META: script=/common/sab.js +// META: script=/html/webappapis/structured-clone/structured-clone-battery-of-tests.js +// META: script=/html/webappapis/structured-clone/structured-clone-battery-of-tests-with-transferables.js +// META: script=/html/webappapis/structured-clone/structured-clone-battery-of-tests-harness.js + +runStructuredCloneBatteryOfTests({ + structuredClone(data, transfer) { + return new Promise(resolve => { + window.addEventListener('message', function f(ev) { + window.removeEventListener('message', f); + resolve(ev.data.data); + }); + window.postMessage({data, transfer}, "/", transfer); + }); + } +}); |