summaryrefslogtreecommitdiffstats
path: root/dom/base/test/test_script_loader_js_cache_module_sri.html
diff options
context:
space:
mode:
Diffstat (limited to 'dom/base/test/test_script_loader_js_cache_module_sri.html')
-rw-r--r--dom/base/test/test_script_loader_js_cache_module_sri.html425
1 files changed, 425 insertions, 0 deletions
diff --git a/dom/base/test/test_script_loader_js_cache_module_sri.html b/dom/base/test/test_script_loader_js_cache_module_sri.html
new file mode 100644
index 0000000000..77ab2b0abe
--- /dev/null
+++ b/dom/base/test/test_script_loader_js_cache_module_sri.html
@@ -0,0 +1,425 @@
+<!DOCTYPE html>
+<html>
+<!-- https://bugzilla.mozilla.org/show_bug.cgi?id=1436400 -->
+<!-- The JS bytecode cache is not supposed to be observable. To make it
+ observable, the ScriptLoader is instrumented to trigger events on the
+ script tag.
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for request fallback for SRI mismatch on module bytecode</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <script type="application/javascript">
+
+// List of testcases
+//
+// prep
+// HTML file loaded in iframe that prepares the bytecode cache
+// prepEvents
+// Non-ordered multi-set of expected events dispatched during loading the
+// "prep" HTML file
+// src
+// HTML file loaded in iframe after preparation finishes
+// events
+// Non-ordered multi-set of expected events dispatched during loading the
+// "src" HTML file
+const tests = [
+ // 1. Module bytecode is saved with integrity
+ // 2. Module bytecode is loaded by script element with integrity
+ {
+ prep: "file_script_module_sri_basic_prep.html",
+ prepEvents: [
+ "scriptloader_load_source",
+ "scriptloader_evaluate_module",
+ "scriptloader_encode",
+ "scriptloader_bytecode_saved",
+ "test_evaluated",
+ ],
+ src: "file_script_module_sri_basic.html",
+ events: [
+ "scriptloader_load_bytecode",
+ "scriptloader_evaluate_module",
+ "test_evaluated",
+ ],
+ },
+
+ // 1. Module bytecode is saved without integrity
+ // 2. Module bytecode is loaded by script element with integrity
+ {
+ prep: "file_script_module_sri_fallback_prep.html",
+ prepEvents: [
+ "scriptloader_load_source",
+ "scriptloader_evaluate_module",
+ "scriptloader_encode",
+ "scriptloader_bytecode_saved",
+ "test_evaluated",
+ ],
+ src: "file_script_module_sri_fallback.html",
+ events: [
+ "scriptloader_load_bytecode",
+ "scriptloader_fallback",
+ "scriptloader_load_source",
+ "scriptloader_evaluate_module",
+ "scriptloader_encode",
+ "scriptloader_bytecode_saved",
+ "test_evaluated",
+ ],
+ },
+
+ // 1. Module bytecode is saved without integrity
+ // 2. Module bytecode is loaded by script element with wrong integrity
+ //
+ // The module script is not evaluated
+ {
+ prep: "file_script_module_sri_fallback_failure_prep.html",
+ prepEvents: [
+ "scriptloader_load_source",
+ "scriptloader_evaluate_module",
+ "scriptloader_encode",
+ "scriptloader_bytecode_saved",
+ "test_evaluated",
+ ],
+ src: "file_script_module_sri_fallback_failure.html",
+ events: [
+ "scriptloader_load_bytecode",
+ "scriptloader_fallback",
+ "scriptloader_load_source",
+
+ // This event is dispatched by another script, after the first module
+ // script load is terminated.
+ "test_evaluated",
+ ],
+ },
+
+ // 1. Module bytecode is saved without integrity
+ // 2. Module bytecode is loaded by script element without integrity, and then
+ // loaded by script element with integrity
+ //
+ // The integrity attribute is ignored because the first request without
+ // integrity is shared between them.
+ {
+ prep: "file_script_module_sri_elem_elem_1_prep.html",
+ prepEvents: [
+ "scriptloader_load_source",
+ "scriptloader_evaluate_module",
+ "scriptloader_encode",
+ "scriptloader_bytecode_saved",
+ "test_evaluated",
+ ],
+ src: "file_script_module_sri_elem_elem_1.html",
+ events: [
+ "scriptloader_load_bytecode",
+ "scriptloader_evaluate_module",
+ "test_evaluated",
+
+ // NOTE: scriptloader_evaluate_module is dispatched even if
+ // the module is already evaluated before and it's evaluation is
+ // skipped this time.
+ "scriptloader_evaluate_module",
+ ],
+ },
+
+ // 1. Module bytecode is saved without integrity
+ // 2. Module bytecode is loaded by script element with integrity, and then
+ // loaded by script element without integrity
+ //
+ // The request with integrity is shared between them.
+ {
+ prep: "file_script_module_sri_elem_elem_2_prep.html",
+ prepEvents: [
+ "scriptloader_load_source",
+ "scriptloader_evaluate_module",
+ "scriptloader_encode",
+ "scriptloader_bytecode_saved",
+ "test_evaluated",
+ ],
+ src: "file_script_module_sri_elem_elem_2.html",
+ events: [
+ "scriptloader_load_bytecode",
+ "scriptloader_fallback",
+ "scriptloader_load_source",
+ "scriptloader_evaluate_module",
+ "scriptloader_encode",
+ "scriptloader_bytecode_saved",
+ "test_evaluated",
+
+ "scriptloader_evaluate_module",
+ ],
+ },
+
+ // 1. Module bytecode is saved without integrity
+ // 2. Module bytecode is loaded by script element with integrity, and then
+ // imported statically.
+ //
+ // The request with integrity is shared between them.
+ {
+ prep: "file_script_module_sri_elem_import_prep.html",
+ prepEvents: [
+ // file_script_module_sri_elem_import_imported.mjs
+ "scriptloader_load_source",
+ "scriptloader_evaluate_module",
+ "scriptloader_encode",
+ "scriptloader_bytecode_saved",
+ "test_evaluated",
+ ],
+ src: "file_script_module_sri_elem_import.html",
+ events: [
+ // file_script_module_sri_elem_import_imported.mjs
+ "scriptloader_load_bytecode",
+ "scriptloader_fallback",
+ "scriptloader_load_source",
+ "scriptloader_evaluate_module",
+ "scriptloader_encode",
+ "scriptloader_bytecode_saved",
+ "test_evaluated",
+
+ // file_script_module_sri_elem_import.mjs
+ "scriptloader_load_source",
+ "scriptloader_evaluate_module",
+ "scriptloader_encode",
+ "scriptloader_bytecode_saved",
+ "test_evaluated",
+ ],
+ },
+
+ // 1. Module bytecode is saved without integrity
+ // 2. Module bytecode is imported statically, and
+ // loaded by script element with integrity
+ //
+ // Even if the import is performed first, the script element's request
+ // with integrity is used because of preload.
+ {
+ prep: "file_script_module_sri_import_elem_prep.html",
+ prepEvents: [
+ // file_script_module_sri_import_elem_imported.mjs
+ "scriptloader_load_source",
+ "scriptloader_evaluate_module",
+ "scriptloader_encode",
+ "scriptloader_bytecode_saved",
+ "test_evaluated",
+ ],
+ src: "file_script_module_sri_import_elem.html",
+ events: [
+ // file_script_module_sri_import_elem.mjs
+ "scriptloader_load_source",
+ "scriptloader_evaluate_module",
+ "scriptloader_encode",
+ "scriptloader_bytecode_saved",
+ "test_evaluated",
+
+ // file_script_module_sri_import_elem_imported.mjs
+ "scriptloader_load_bytecode",
+ "scriptloader_fallback",
+ "scriptloader_load_source",
+ "scriptloader_evaluate_module",
+ "scriptloader_encode",
+ "scriptloader_bytecode_saved",
+ "test_evaluated",
+ ],
+ },
+
+ // 1. Module bytecode is saved without integrity
+ // 2. Module bytecode is imported statically, and
+ // loaded by script element with integrity, without preload
+ //
+ // The request without integrity triggered by import is shared between
+ // them.
+ {
+ prep: "file_script_module_sri_import_elem_nopreload_prep.html",
+ prepEvents: [
+ // file_script_module_sri_import_elem_nopreload_imported.mjs
+ "scriptloader_load_source",
+ "scriptloader_evaluate_module",
+ "scriptloader_encode",
+ "scriptloader_bytecode_saved",
+ "test_evaluated",
+ ],
+ src: "file_script_module_sri_import_elem_nopreload.html",
+ events: [
+ // file_script_module_sri_import_elem_nopreload.mjs
+ "scriptloader_load_source",
+ "scriptloader_evaluate_module",
+ "scriptloader_encode",
+ "scriptloader_bytecode_saved",
+ "test_evaluated",
+
+ // file_script_module_sri_import_elem_nopreload_imported.mjs
+ "scriptloader_load_bytecode",
+ "scriptloader_evaluate_module",
+ "test_evaluated",
+ ],
+ },
+
+ // 1. Module bytecode is saved without integrity
+ // 2. Module bytecode is loaded by script element with integrity, and then
+ // imported dynamically.
+ //
+ // The request with integrity is shared between them.
+ {
+ prep: "file_script_module_sri_elem_dynamic_prep.html",
+ prepEvents: [
+ // file_script_module_sri_elem_dynamic_imported.mjs
+ "scriptloader_load_source",
+ "scriptloader_evaluate_module",
+ "scriptloader_encode",
+ "scriptloader_bytecode_saved",
+ "test_evaluated",
+ ],
+ src: "file_script_module_sri_elem_dynamic.html",
+ events: [
+ // file_script_module_sri_elem_dynamic_imported.mjs
+ "scriptloader_load_bytecode",
+ "scriptloader_fallback",
+ "scriptloader_load_source",
+ "scriptloader_evaluate_module", // (element)
+ "scriptloader_evaluate_module", // (dynamic)
+ "scriptloader_encode",
+ "scriptloader_bytecode_saved",
+ "test_evaluated",
+
+ // file_script_module_sri_elem_dynamic.mjs
+ "scriptloader_load_source",
+ "scriptloader_evaluate_module",
+ "scriptloader_encode",
+ "scriptloader_bytecode_saved",
+ "test_evaluated",
+ ],
+ },
+
+ // 1. Module bytecode is saved without integrity
+ // 2. Module bytecode is imported dynamically, and then
+ // loaded by script element with integrity
+ //
+ // Even if the dynamic import is performed first, the script element's
+ // request with integrity is used because of preload.
+ {
+ prep: "file_script_module_sri_dynamic_elem_prep.html",
+ prepEvents: [
+ // file_script_module_sri_dynamic_elem_imported.mjs
+ "scriptloader_load_source",
+ "scriptloader_evaluate_module",
+ "scriptloader_encode",
+ "scriptloader_bytecode_saved",
+ "test_evaluated",
+ ],
+ src: "file_script_module_sri_dynamic_elem.html",
+ events: [
+ // file_script_module_sri_dynamic_elem_imported.mjs
+ "scriptloader_load_bytecode",
+ "scriptloader_fallback",
+ "scriptloader_load_source",
+ "scriptloader_evaluate_module", // (element)
+ "scriptloader_evaluate_module", // (dynamic)
+ "scriptloader_encode",
+ "test_evaluated",
+
+ // file_script_module_sri_dynamic_elem.mjs
+ "scriptloader_load_source",
+ "scriptloader_evaluate_module",
+ "scriptloader_encode",
+ "scriptloader_bytecode_saved",
+ "test_evaluated",
+ ],
+ },
+
+ // 1. Module bytecode is saved without integrity
+ // 2. Module bytecode is imported dynamically, and then
+ // loaded by script element with integrity, without preload
+ //
+ // The request without integrity triggered by dynamic import is shared
+ // between them.
+ {
+ prep: "file_script_module_sri_dynamic_elem_nopreload_prep.html",
+ prepEvents: [
+ // file_script_module_sri_dynamic_elem_nopreload_imported.mjs
+ "scriptloader_load_source",
+ "scriptloader_evaluate_module",
+ "scriptloader_encode",
+ "scriptloader_bytecode_saved",
+ "test_evaluated",
+ ],
+ src: "file_script_module_sri_dynamic_elem_nopreload.html",
+ events: [
+ // file_script_module_sri_dynamic_elem_nopreload_imported.mjs
+ "scriptloader_load_bytecode",
+ "scriptloader_evaluate_module", // (element)
+ "scriptloader_evaluate_module", // (dynamic)
+ "test_evaluated",
+
+ // file_script_module_sri_dynamic_elem_nopreload.mjs
+ "scriptloader_load_source",
+ "scriptloader_evaluate_module",
+ "scriptloader_encode",
+ "scriptloader_bytecode_saved",
+ "test_evaluated",
+ ],
+ },
+];
+
+promise_test(async function() {
+ await SpecialPowers.pushPrefEnv({set: [
+ ['dom.script_loader.bytecode_cache.enabled', true],
+ ['dom.expose_test_interfaces', true],
+ ['dom.script_loader.bytecode_cache.strategy', -1]
+ ]});
+
+ for (const { prep, prepEvents, src, events } of tests) {
+ for (let i = 0; i < 2; i++) {
+ const expectedEvents = i == 0 ? prepEvents : events;
+ const currentSrc = i == 0 ? prep : src;
+
+ const iframe = document.createElement("iframe");
+ document.body.appendChild(iframe);
+
+ const iwin = iframe.contentWindow;
+
+ dump("## Start: " + currentSrc + "\n");
+ let observedEvents = [];
+ await new Promise(resolve => {
+ function logEvent(evt) {
+ if (evt.type != "test_evaluated") {
+ if (!/^watchme/.test(evt.target.id)) {
+ return;
+ }
+ }
+ dump("## ScriptLoader event: " + evt.type + "\n");
+ observedEvents.push(evt.type);
+ if (observedEvents.length == expectedEvents.length) {
+ resolve();
+ }
+ }
+ iwin.addEventListener("scriptloader_load_source", logEvent);
+ iwin.addEventListener("scriptloader_load_bytecode", logEvent);
+ iwin.addEventListener("scriptloader_execute", logEvent);
+ iwin.addEventListener("scriptloader_evaluate_module", logEvent);
+ iwin.addEventListener("scriptloader_encode", logEvent);
+ iwin.addEventListener("scriptloader_no_encode", logEvent);
+ iwin.addEventListener("scriptloader_bytecode_saved", logEvent);
+ iwin.addEventListener("scriptloader_bytecode_failed", logEvent);
+ iwin.addEventListener("scriptloader_fallback", logEvent);
+ iwin.addEventListener("test_evaluated", logEvent);
+ iframe.src = currentSrc;
+ });
+
+ // The event order is non-deterministic.
+ // Just compare them as multi-set.
+ expectedEvents.sort();
+ observedEvents.sort();
+ assert_equals(
+ JSON.stringify(observedEvents),
+ JSON.stringify(expectedEvents),
+ `Expected events should be observed for ${currentSrc}`);
+
+ document.body.removeChild(iframe);
+ }
+ }
+}, "Test module bytecode save and load");
+
+done();
+ </script>
+ <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1436400">Mozilla Bug 1436400</a>
+</body>
+</html>