diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /testing/web-platform/tests/wasm/serialization | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/wasm/serialization')
39 files changed, 857 insertions, 0 deletions
diff --git a/testing/web-platform/tests/wasm/serialization/arraybuffer/transfer.window.js b/testing/web-platform/tests/wasm/serialization/arraybuffer/transfer.window.js new file mode 100644 index 0000000000..0258581b1e --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/arraybuffer/transfer.window.js @@ -0,0 +1,11 @@ +test(() => { + const buffer = new WebAssembly.Memory({initial: 4}).buffer; + postMessage(buffer, '*'); +}, "Serializing a WebAssembly.Memory-backed ArrayBuffer works"); + +test(() => { + const buffer = new WebAssembly.Memory({initial: 4}).buffer; + assert_throws_js(TypeError, () => { + postMessage('foo', '*', [buffer]); + }); +}, "Transfering a WebAssembly.Memory-backed ArrayBuffer throws"); diff --git a/testing/web-platform/tests/wasm/serialization/module/broadcastchannel-success-and-failure.html b/testing/web-platform/tests/wasm/serialization/module/broadcastchannel-success-and-failure.html new file mode 100644 index 0000000000..0d11cc595b --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/broadcastchannel-success-and-failure.html @@ -0,0 +1,38 @@ +<!doctype html> +<!-- Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/ --> +<title>WebAssembly.Module cannot cross agent clusters, BroadcastChannel edition</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="./resources/test-incrementer.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) { + createWasmModule().then(module => { + channel.postMessage(module); + }); + } 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/wasm/serialization/module/broadcastchannel-success.html b/testing/web-platform/tests/wasm/serialization/module/broadcastchannel-success.html new file mode 100644 index 0000000000..ddc242b82e --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/broadcastchannel-success.html @@ -0,0 +1,59 @@ +<!DOCTYPE html> +<!-- Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/ --> +<meta charset="utf-8"> +<title>Structured cloning of WebAssembly.Module: BroadcastChannel within the same agent cluster</title> +<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 => { + return createWasmModule().then(module => { + let loadedIframes = 0; + return Promise.all([ + createIFrame("resources/broadcastchannel-iframe.html"), + createIFrame("resources/broadcastchannel-iframe.html"), + createIFrame("resources/broadcastchannel-iframe.html") + ]).then(() => { + const thisIframe = loadedIframes++; + const channel = new BroadcastChannel("channel name"); + + return new Promise(resolve => { + let soFar = 0; + channel.onmessage = t.step_func(msg => { + if (msg.module) { + // We only care about "broadcasts" from the workers. + return; + } + + let {i, result} = msg.data; + + assert_in_array(i, [0, 1, 2], "Any message events must come from expected sources"); + assert_equals(result, i + 1, `iframe ${i} must return ${i+1}`); + ++soFar; + + if (soFar === 3) { + resolve(); + } + }); + + channel.postMessage({ module, i: thisIframe }); + }); + }); + }); +}); + +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/wasm/serialization/module/cross-origin-module-sharing-fails.html b/testing/web-platform/tests/wasm/serialization/module/cross-origin-module-sharing-fails.html new file mode 100644 index 0000000000..cd3e99b9ec --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/cross-origin-module-sharing-fails.html @@ -0,0 +1,38 @@ +<title>Postmessage of a WebAssembly.Module cross-origin fails with a messageerror</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> +<script src="resources/test-incrementer.js"></script> + +<body> +<script> +async function testPostMessageErrorForOrigin(t, remoteOrigin){ + const iframe = document.createElement('iframe'); + iframe.src = `${remoteOrigin}${base_path()}resources/incrementer-iframe-failure.html`; + const iframeLoaded = new Promise(resolve => iframe.onload = resolve); + document.body.appendChild(iframe); + t.add_cleanup(() => { + iframe.remove(); + }); + await iframeLoaded; + + const module = await createWasmModule(); + const messageErrorReceived = + new Promise(resolve => window.onmessage = resolve); + iframe.contentWindow.postMessage({message: 'send module', module}, "*"); + let reply = await messageErrorReceived; + assert_equals('messageerror received', reply.data); +} + +promise_test(async t => { + const remoteOrigin = get_host_info().OTHER_ORIGIN; + await testPostMessageErrorForOrigin(t, remoteOrigin); +}, "postMessaging a wasm module to an iframe in a different agent cluster fails"); + +promise_test(async t => { + const remoteOrigin = get_host_info().HTTPS_ORIGIN; + await testPostMessageErrorForOrigin(t, remoteOrigin); +}, "postMessaging a wasm module to a cross-origin iframe in the same agent cluster fails"); +</script> +</body> diff --git a/testing/web-platform/tests/wasm/serialization/module/identity-not-preserved.html b/testing/web-platform/tests/wasm/serialization/module/identity-not-preserved.html new file mode 100644 index 0000000000..24bb3b16d8 --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/identity-not-preserved.html @@ -0,0 +1,66 @@ +<!DOCTYPE html> +<!-- Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/ --> +<meta charset="utf-8"> +<title>WebAssembly.Modules, when cloned, do not give back the same object</title> +<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"; + +async_test(t => { + createWasmModule().then(module => { + window.addEventListener("message", t.step_func(({ data }) => { + if (data.testId !== 1) { + return; + } + + assert_not_equals(data.module, module); + + t.done(); + })); + + window.postMessage({ module, testId: 1 }, "*"); + }); +}, "postMessaging to this window does not give back the same WebAssembly.Module"); + +async_test(t => { + createWasmModule().then(module => { + const worker = new Worker("resources/echo-worker.js"); + + worker.addEventListener("message", t.step_func(({ data }) => { + if (data.testId !== 2) { + return; + } + + assert_not_equals(data.module, module); + t.done(); + })); + + worker.postMessage({ testId: 2, module }); + }); +}, "postMessaging to a worker and back does not give back the same WebAssembly.Module"); + +async_test(t => { + createWasmModule().then(module => { + window.addEventListener("message", t.step_func(({ data }) => { + if (data.testId !== 3) { + return; + } + + assert_not_equals(data.module, module); + t.done(); + })); + + const iframe = document.createElement("iframe"); + iframe.onload = t.step_func(() => { + iframe.contentWindow.postMessage({ testId: 3, module }, "*"); + }); + iframe.src = "resources/echo-iframe.html"; + document.body.appendChild(iframe); + }); +}, "postMessaging to an iframe and back does not give back the same WebAssembly.Module"); +</script> diff --git a/testing/web-platform/tests/wasm/serialization/module/incrementer.wasm b/testing/web-platform/tests/wasm/serialization/module/incrementer.wasm Binary files differnew file mode 100644 index 0000000000..47afcdef2a --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/incrementer.wasm diff --git a/testing/web-platform/tests/wasm/serialization/module/nested-worker-success.any.js b/testing/web-platform/tests/wasm/serialization/module/nested-worker-success.any.js new file mode 100644 index 0000000000..84fbd92a29 --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/nested-worker-success.any.js @@ -0,0 +1,9 @@ +// META: global=dedicatedworker,sharedworker +// META: script=resources/test-incrementer.js +"use strict"; + +promise_test(t => { + const worker = new Worker("resources/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"); diff --git a/testing/web-platform/tests/wasm/serialization/module/no-transferring.html b/testing/web-platform/tests/wasm/serialization/module/no-transferring.html new file mode 100644 index 0000000000..2f0f674b1f --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/no-transferring.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<!-- Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/ --> +<meta charset="utf-8"> +<title>WebAssembly.Modules cannot be transferred</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="./resources/create-empty-wasm-module.js"></script> + +<script> +"use strict"; + +test(() => { + const module = createEmptyWasmModule(); + assert_throws_dom("DataCloneError", () => window.postMessage(module, "*", [module])); + assert_throws_dom("DataCloneError", () => window.postMessage("test", "*", [module])); +}, "Trying to transfer a WebAssembly.Module to this window throws"); + +test(() => { + const module = createEmptyWasmModule(); + const worker = new Worker("resources/echo-worker.js"); + assert_throws_dom("DataCloneError", () => worker.postMessage(module, [module])); + assert_throws_dom("DataCloneError", () => worker.postMessage("test", [module])); +}, "Trying to transfer a WebAssembly.Module to a worker throws"); + +test(() => { + const module = createEmptyWasmModule(); + const channel = new MessageChannel(); + assert_throws_dom("DataCloneError", () => channel.port1.postMessage(module, [module])); + assert_throws_dom("DataCloneError", () => channel.port1.postMessage("test", [module])); +}, "Trying to transfer a WebAssembly.Module through a MessagePort throws"); +</script> diff --git a/testing/web-platform/tests/wasm/serialization/module/resources/blank.html b/testing/web-platform/tests/wasm/serialization/module/resources/blank.html new file mode 100644 index 0000000000..a3c3a4689a --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/resources/blank.html @@ -0,0 +1,2 @@ +<!DOCTYPE html> +<title>Empty doc</title> diff --git a/testing/web-platform/tests/wasm/serialization/module/resources/broadcastchannel-iframe.html b/testing/web-platform/tests/wasm/serialization/module/resources/broadcastchannel-iframe.html new file mode 100644 index 0000000000..83e347b5cb --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/resources/broadcastchannel-iframe.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>A test page that uses a given WebAssembly.Module sent from a BroadcastChannel</title> + +<script> +"use strict"; +const channel = new BroadcastChannel("channel name"); + +channel.onmessage = ({ data: { module, i }, source }) => { + if (!module) { + // We only care about "broadcasts" from the window + return; + } + + let instance = new WebAssembly.Instance(module); + let increment = instance.exports["increment"]; + let result = increment(i); + channel.postMessage({i, result}); +}; +</script> diff --git a/testing/web-platform/tests/wasm/serialization/module/resources/broadcastchannel-sharedworker.js b/testing/web-platform/tests/wasm/serialization/module/resources/broadcastchannel-sharedworker.js new file mode 100644 index 0000000000..310e0e9358 --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/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/wasm/serialization/module/resources/broadcastchannel-worker.js b/testing/web-platform/tests/wasm/serialization/module/resources/broadcastchannel-worker.js new file mode 100644 index 0000000000..76a8177060 --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/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 WebAssembly.Module) { + channel.postMessage("dw-success"); + } +} +channel.postMessage("hi"); diff --git a/testing/web-platform/tests/wasm/serialization/module/resources/create-empty-wasm-module.js b/testing/web-platform/tests/wasm/serialization/module/resources/create-empty-wasm-module.js new file mode 100644 index 0000000000..7326710c9e --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/resources/create-empty-wasm-module.js @@ -0,0 +1,4 @@ +function createEmptyWasmModule() { + return new WebAssembly.Module( + new Uint8Array([0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00])); +} diff --git a/testing/web-platform/tests/wasm/serialization/module/resources/echo-iframe.html b/testing/web-platform/tests/wasm/serialization/module/resources/echo-iframe.html new file mode 100644 index 0000000000..c4fd5824a1 --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/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/wasm/serialization/module/resources/echo-worker.js b/testing/web-platform/tests/wasm/serialization/module/resources/echo-worker.js new file mode 100644 index 0000000000..cbbde8a73c --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/resources/echo-worker.js @@ -0,0 +1,5 @@ +"use strict"; + +self.onmessage = ({ data }) => { + self.postMessage(data); +}; diff --git a/testing/web-platform/tests/wasm/serialization/module/resources/incrementer-iframe-domain.sub.html b/testing/web-platform/tests/wasm/serialization/module/resources/incrementer-iframe-domain.sub.html new file mode 100644 index 0000000000..d2d18de499 --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/resources/incrementer-iframe-domain.sub.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>A test page that is sent a WebAssembly Module</title> +<script src="/resources/testharness.js"></script> +<script src="test-incrementer.js"></script> + +<script> +"use strict"; + +document.domain = "{{host}}"; +setupDestinationIncrementer(self, parent, "*"); +</script> diff --git a/testing/web-platform/tests/wasm/serialization/module/resources/incrementer-iframe-failure.html b/testing/web-platform/tests/wasm/serialization/module/resources/incrementer-iframe-failure.html new file mode 100644 index 0000000000..5212a9ec72 --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/resources/incrementer-iframe-failure.html @@ -0,0 +1,5 @@ +<title>A test page that is sent a WebAssembly Module cross-origin cannot receive it</title> + +<script> +self.onmessageerror = () => parent.postMessage('messageerror received', "*"); +</script> diff --git a/testing/web-platform/tests/wasm/serialization/module/resources/incrementer-iframe.html b/testing/web-platform/tests/wasm/serialization/module/resources/incrementer-iframe.html new file mode 100644 index 0000000000..5c8bc0735e --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/resources/incrementer-iframe.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>A test page that is sent a WebAssembly Module</title> +<script src="/resources/testharness.js"></script> +<script src="test-incrementer.js"></script> + +<script> +"use strict"; + +setupDestinationIncrementer(self, parent, "*"); +</script> diff --git a/testing/web-platform/tests/wasm/serialization/module/resources/incrementer-popup.html b/testing/web-platform/tests/wasm/serialization/module/resources/incrementer-popup.html new file mode 100644 index 0000000000..660e472b27 --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/resources/incrementer-popup.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>A test page that is sent a WebAssembly Module</title> +<script src="/resources/testharness.js"></script> +<script src="test-incrementer.js"></script> + +<script> +"use strict"; + +setupDestinationIncrementer(self, opener, "*"); +</script> diff --git a/testing/web-platform/tests/wasm/serialization/module/resources/incrementer-worker-with-channel.js b/testing/web-platform/tests/wasm/serialization/module/resources/incrementer-worker-with-channel.js new file mode 100644 index 0000000000..0323b3e52e --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/resources/incrementer-worker-with-channel.js @@ -0,0 +1,8 @@ +"use strict"; +importScripts("/resources/testharness.js"); +importScripts("./test-incrementer.js"); + +self.onmessage = ({ data }) => { + // data will be a MessagePort + setupDestinationIncrementer(data, data); +}; diff --git a/testing/web-platform/tests/wasm/serialization/module/resources/incrementer-worker.js b/testing/web-platform/tests/wasm/serialization/module/resources/incrementer-worker.js new file mode 100644 index 0000000000..1779ceea52 --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/resources/incrementer-worker.js @@ -0,0 +1,5 @@ +"use strict"; +importScripts("/resources/testharness.js"); +importScripts("./test-incrementer.js"); + +setupDestinationIncrementer(self, self); diff --git a/testing/web-platform/tests/wasm/serialization/module/resources/incrementer.wasm b/testing/web-platform/tests/wasm/serialization/module/resources/incrementer.wasm Binary files differnew file mode 100644 index 0000000000..47afcdef2a --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/resources/incrementer.wasm diff --git a/testing/web-platform/tests/wasm/serialization/module/resources/nested-iframe-1.html b/testing/web-platform/tests/wasm/serialization/module/resources/nested-iframe-1.html new file mode 100644 index 0000000000..fe93cc0c4b --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/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/wasm/serialization/module/resources/nested-iframe-2.html b/testing/web-platform/tests/wasm/serialization/module/resources/nested-iframe-2.html new file mode 100644 index 0000000000..fad52ce9de --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/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/wasm/serialization/module/resources/nested-iframe-3.html b/testing/web-platform/tests/wasm/serialization/module/resources/nested-iframe-3.html new file mode 100644 index 0000000000..7971022b2c --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/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/wasm/serialization/module/resources/nested-iframe-4-incrementer.html b/testing/web-platform/tests/wasm/serialization/module/resources/nested-iframe-4-incrementer.html new file mode 100644 index 0000000000..f419f4bc36 --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/resources/nested-iframe-4-incrementer.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>A test page that is sent a WebAssembly Module, nested 4 levels deep in iframes</title> +<script src="/resources/testharness.js"></script> +<script src="test-incrementer.js"></script> + +<script> +"use strict"; + +setupDestinationIncrementer(self, parent.parent.parent.parent.parent, "*"); +</script> diff --git a/testing/web-platform/tests/wasm/serialization/module/resources/serviceworker-failure.js b/testing/web-platform/tests/wasm/serialization/module/resources/serviceworker-failure.js new file mode 100644 index 0000000000..4ef380c253 --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/resources/serviceworker-failure.js @@ -0,0 +1,35 @@ +// Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/. +"use strict"; +self.importScripts("/resources/testharness.js"); +self.importScripts("./create-empty-wasm-module.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 WebAssembly.Module"; + } else if (e.data === "we are expecting a messageerror due to the worker sending us a WebAssembly.Module") { + assert_equals(state, "onmessageerror was received in worker"); + e.source.postMessage(createEmptyWasmModule()); + 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 WebAssembly.Module") { + 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/wasm/serialization/module/resources/sharedworker-failure.js b/testing/web-platform/tests/wasm/serialization/module/resources/sharedworker-failure.js new file mode 100644 index 0000000000..854c70b9e8 --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/resources/sharedworker-failure.js @@ -0,0 +1,21 @@ +importScripts("./test-incrementer.js"); +importScripts("./create-empty-wasm-module.js"); + +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(createEmptyWasmModule()) + } 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/wasm/serialization/module/resources/test-incrementer.js b/testing/web-platform/tests/wasm/serialization/module/resources/test-incrementer.js new file mode 100644 index 0000000000..65cb33227a --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/resources/test-incrementer.js @@ -0,0 +1,57 @@ +// Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/. +// +// This file is simplified from the one there, because it only tests that the +// module can be passed and that functions can be run. The SharedArrayBuffer +// version also tests that the memory is shared between the agents. + +"use strict"; + +function createWasmModule() { + return fetch('incrementer.wasm') + .then(response => { + if (!response.ok) + throw new Error(response.statusText); + return response.arrayBuffer(); + }) + .then(WebAssembly.compile); +} + +function testModule(module) { + let instance = new WebAssembly.Instance(module); + let increment = instance.exports["increment"]; + assert_equals(typeof increment, "function", `The type of the increment export should be "function", got ${typeof increment}`); + let result = increment(42); + assert_equals(result, 43, `increment(42) should be 43, got ${result}`); +} + +self.testSharingViaIncrementerScript = (t, whereToListen, whereToListenLabel, whereToSend, whereToSendLabel, origin) => { + return createWasmModule().then(module => { + return new Promise(resolve => { + + whereToListen.onmessage = t.step_func(({ data }) => { + switch (data.message) { + case "module received": { + testModule(data.module); + resolve(); + break; + } + } + }); + + whereToSend.postMessage({ message: "send module", module }, origin); + }); + }); +}; + +self.setupDestinationIncrementer = (whereToListen, whereToSendBackTo, origin) => { + whereToListen.onmessage = ({ data }) => { + switch (data.message) { + case "send module": { + let module = data.module; + testModule(data.module); + whereToSendBackTo.postMessage({ message: "module received", module }, origin); + break; + } + } + }; +}; diff --git a/testing/web-platform/tests/wasm/serialization/module/serialization-via-history.html b/testing/web-platform/tests/wasm/serialization/module/serialization-via-history.html new file mode 100644 index 0000000000..38d4301d70 --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/serialization-via-history.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<!-- Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/ --> +<meta charset="utf-8"> +<title>WebAssembly.Module cloning via history's methods invoking StructuredSerializeForStorage</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="./resources/create-empty-wasm-module.js"></script> + +<script> +"use strict"; + +for (const method of ["pushState", "replaceState"]) { + test(() => { + assert_throws_dom("DataCloneError", () => { + history[method](createEmptyWasmModule(), "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; } }, + createEmptyWasmModule(), + { get x() { getter2Called = true; return 5; } } + ], "dummy title"); + }); + + assert_true(getter1Called, "The getter before the WebAssembly.Module must have been called"); + assert_false(getter2Called, "The getter after the WebAssembly.Module must not have been called"); + }, `history.${method}(): is interleaved correctly`); +} +</script> diff --git a/testing/web-platform/tests/wasm/serialization/module/serialization-via-idb.any.js b/testing/web-platform/tests/wasm/serialization/module/serialization-via-idb.any.js new file mode 100644 index 0000000000..2591d2fe74 --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/serialization-via-idb.any.js @@ -0,0 +1,45 @@ +// META: script=/IndexedDB/resources/support.js +"use strict"; + +function createEmptyWasmModule() { + return new WebAssembly.Module( + new Uint8Array([0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00])); +} + +async_test(t => { + const openReq = createdb(t); + + openReq.onupgradeneeded = e => { + const db = e.target.result; + const store = db.createObjectStore("store", { keyPath: "key" }); + + assert_throws_dom("DataCloneError", () => { + store.put({ key: 1, property: createEmptyWasmModule() }); + }); + t.done(); + }; +}, "WebAssembly.Module 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" }); + + let getter1Called = false; + let getter2Called = false; + + assert_throws_dom("DataCloneError", () => { + store.put({ key: 1, property: [ + { get x() { getter1Called = true; return 5; } }, + createEmptyWasmModule(), + { get x() { getter2Called = true; return 5; } } + ]}); + }); + + assert_true(getter1Called, "The getter before the WebAssembly.Module must have been called"); + assert_false(getter2Called, "The getter after the WebAssembly.Module must not have been called"); + t.done(); + }; +}, "WebAssembly.Module cloning via the IndexedDB: is interleaved correctly"); diff --git a/testing/web-platform/tests/wasm/serialization/module/serialization-via-notifications-api.any.js b/testing/web-platform/tests/wasm/serialization/module/serialization-via-notifications-api.any.js new file mode 100644 index 0000000000..3672192df7 --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/serialization-via-notifications-api.any.js @@ -0,0 +1,28 @@ +"use strict"; + +function createEmptyWasmModule() { + return new WebAssembly.Module( + new Uint8Array([0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00])); +} + +test(() => { + assert_throws_dom("DataCloneError", () => { + new Notification("Bob: Hi", { data: createEmptyWasmModule() }); + }) +}, "WebAssembly.Module cloning via the Notifications API's data member: basic case"); + +test(() => { + let getter1Called = false; + let getter2Called = false; + + assert_throws_dom("DataCloneError", () => { + new Notification("Bob: Hi", { data: [ + { get x() { getter1Called = true; return 5; } }, + createEmptyWasmModule(), + { 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"); +}, "WebAssembly.Module cloning via the Notifications API's data member: is interleaved correctly"); diff --git a/testing/web-platform/tests/wasm/serialization/module/share-module-cross-origin-fails.sub.html b/testing/web-platform/tests/wasm/serialization/module/share-module-cross-origin-fails.sub.html new file mode 100644 index 0000000000..5a52b96698 --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/share-module-cross-origin-fails.sub.html @@ -0,0 +1,31 @@ +<title>Postmessage of a WebAssembly.Module cross-origin fails with a messageerror</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="./resources/test-incrementer.js"></script> + +<body></body> + +<script> +promise_test(async t => { + // Create an iframe. It will notify this document when the "messageerror" + // event is triggered. + const iframe = document.createElement("iframe"); + iframe.src = "//{{domains[www1]}}:{{location[port]}}" + + "/wasm/serialization/module/resources/incrementer-iframe-failure.html"; + + // Instantiate and wait for the document to be loaded. + const iframeLoaded = new Promise(resolve => iframe.onload = resolve); + document.body.appendChild(iframe); + await iframeLoaded; + + const module = await createWasmModule(); + const messageErrorReceived = new Promise(resolve => { + window.onmessage = ({data}) => { + if (data == 'messageerror received') + resolve(); + }; + }); + iframe.contentWindow.postMessage({message: 'send module', module}, "*"); + await messageErrorReceived; +}, "postMessaging a wasm module to a cross-origin iframe fails"); +</script> diff --git a/testing/web-platform/tests/wasm/serialization/module/window-domain-success.sub.html b/testing/web-platform/tests/wasm/serialization/module/window-domain-success.sub.html new file mode 100644 index 0000000000..07360d8264 --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/window-domain-success.sub.html @@ -0,0 +1,26 @@ +<!DOCTYPE html> +<!-- Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/ --> +<meta charset="utf-8"> +<title>Structured cloning of WebAssembly.Module into same-origin-domain windows</title> +<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"; +document.domain = "{{host}}"; + +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 = "//{{domains[www1]}}:{{location[port]}}/wasm/serialization/module/resources/incrementer-iframe-domain.sub.html"; + document.body.appendChild(iframe); + }); +}, "postMessaging to a same-origin-domain (but not same-origin) iframe allows them to instantiate"); + +</script> diff --git a/testing/web-platform/tests/wasm/serialization/module/window-messagechannel-success.html b/testing/web-platform/tests/wasm/serialization/module/window-messagechannel-success.html new file mode 100644 index 0000000000..e686c81135 --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/window-messagechannel-success.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<!-- Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/ --> +<meta charset="utf-8"> +<title>Structured cloning of WebAssembly.Module using MessageChannel</title> +<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 instantiate"); +</script> diff --git a/testing/web-platform/tests/wasm/serialization/module/window-serviceworker-failure.https.html b/testing/web-platform/tests/wasm/serialization/module/window-serviceworker-failure.https.html new file mode 100644 index 0000000000..d7285e2fa3 --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/window-serviceworker-failure.https.html @@ -0,0 +1,56 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<!-- Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/ --> +<title>WebAssembly.Module cannot cross agent clusters, service worker edition</title> +<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 src="./resources/create-empty-wasm-module.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(createEmptyWasmModule()); + 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 WebAssembly.Module"; + 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 WebAssembly.Module"); + + 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/wasm/serialization/module/window-sharedworker-failure.html b/testing/web-platform/tests/wasm/serialization/module/window-sharedworker-failure.html new file mode 100644 index 0000000000..667e985a30 --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/window-sharedworker-failure.html @@ -0,0 +1,33 @@ +<!doctype html> +<!-- Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/ --> +<title>WebAssembly.Modules cannot cross agent clusters, shared worker edition</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="./resources/create-empty-wasm-module.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(createEmptyWasmModule()) + } 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/wasm/serialization/module/window-similar-but-cross-origin-success.sub.html b/testing/web-platform/tests/wasm/serialization/module/window-similar-but-cross-origin-success.sub.html new file mode 100644 index 0000000000..a615547de0 --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/window-similar-but-cross-origin-success.sub.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<!-- Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/ --> +<meta charset="utf-8"> +<title>Structured cloning of WebAssembly.Module to similar-origin, but not same-origin, windows</title> +<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"; +document.domain = "{{host}}"; + +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 = "//{{domains[www1]}}:{{location[port]}}/wasm/serialization/module/resources/incrementer-iframe.html"; + document.body.appendChild(iframe); + }); +}, "postMessaging to a not same-origin-domain, but similar origin, iframe allows them to instantiate"); +</script> diff --git a/testing/web-platform/tests/wasm/serialization/module/window-simple-success.html b/testing/web-platform/tests/wasm/serialization/module/window-simple-success.html new file mode 100644 index 0000000000..6f2ccf465e --- /dev/null +++ b/testing/web-platform/tests/wasm/serialization/module/window-simple-success.html @@ -0,0 +1,57 @@ +<!DOCTYPE html> +<!-- Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/ --> +<meta charset="utf-8"> +<title>Structured cloning of WebAssembly.Module: simple success cases that don't need dedicated files</title> +<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.js"); + + return testSharingViaIncrementerScript(t, worker, "window", worker, "worker", undefined); +}, "postMessaging to a dedicated worker allows them to instantiate"); + +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 instantiate"); + +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 instantiate"); + +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 instantiate"); + +</script> |