Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test has a WPT meta file that expects 4 subtest issues.
- This WPT test may be referenced by the following Test IDs:
- /import-maps/dynamic-integrity.html - WPT Dashboard Interop Dashboard
<!DOCTYPE html>
<html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script type="importmap">
{
"imports": {
"./resources/log.js?pipe=sub&name=ResolvesToBadHash": "./resources/log.js?pipe=sub&name=BadHash",
"./resources/log.js?pipe=sub&name=ResolvesToNoHash": "./resources/log.js?pipe=sub&name=NoHash",
"./resources/log.js?pipe=sub&name=GoodHash": "./resources/log.js?pipe=sub&name=GoodHash",
"bare": "./resources/log.js?pipe=sub&name=BareURL",
"bare2": "./resources/log.js?pipe=sub&name=F"
},
"integrity": {
"./resources/log.js?pipe=sub&name=BadHash": "sha384-foobar",
"./resources/log.js?pipe=sub&name=ResolvesToNoHash": "sha384-foobar",
"./resources/log.js?pipe=sub&name=GoodHash": "sha384-SwfgBqInhSlLziU454cYhGgwPpae+d3VHZcY+vjZIO/gxRGt2u3Jsfyvure/Ww0u",
"./resources/log.js?pipe=sub&name=InvalidExtra": "sha384-WsKk8nzJFPhk/4pWR4LYoPhEu3xaAc6PdIm4vmqoZVWqEgMYmZgOg9XJKxgD1+8v foobar-rOJN8igD0+jW6lwNN3+InhXTgQztVHlq/HJ0riswXp8kMoiIDx5JpmCwuVem6Ll9q2LFNSu1xq23bsBMMQk1rg==",
"./resources/log.js?pipe=sub&name=Suffix": "sha384-lbOWldbmji7sCHI/L8iVJ+elmFIMp41p+aYOLxqQfZMqtoFeHFVe/ASRA0IyZ1/9?foobar",
"./resources/log.js?pipe=sub&name=Multiple": "sha384-foobar sha512-rOJN8igD0+jW6lwNN3+InhXTgQztVHlq/HJ0riswXp8kMoiIDx5JpmCwuVem6Ll9q2LFNSu1xq23bsBMMQk1rg==",
"./resources/log.js?pipe=sub&name=BadHashWithNoImport": "sha384-foobar",
"./resources/log.js?pipe=sub&name=BareURL": "sha384-foobar",
"./resources/log.js?pipe=sub&name=EventHandlerPass": "sha384-d4yrBK8a55vlyYz2QEnlaU64PPpdKBkblD2KmfozI61mC1ij6RrZJaGCTsVxPuJ2",
"./resources/log.js?pipe=sub&name=EventHandlerFail": "sha384-foobar",
"bare2": "sha384-foobar",
"resources/log.js?pipe=sub&name=Bare": "sha384-foobar"
}
}
</script>
<script>
let log;
const test_not_loaded = (url, description) => {
promise_test(async t => {
log = [];
await promise_rejects_js(t, TypeError, import(url));
assert_array_equals(log, []);
}, description);
};
const test_loaded = (url, log_expectation, description) => {
promise_test(async t => {
log = [];
await import(url);
assert_array_equals(log, log_expectation);
}, description);
};
test_not_loaded(
"./resources/log.js?pipe=sub&name=ResolvesToBadHash",
"script was not loaded, as its resolved URL failed its integrity check"
);
test_loaded(
"./resources/log.js?pipe=sub&name=ResolvesToNoHash",
["log:NoHash"],
"script was loaded, as its resolved URL had no integrity check, despite its specifier having one"
);
test_loaded(
"./resources/log.js?pipe=sub&name=GoodHash",
["log:GoodHash"],
"script was loaded, as its integrity check passed"
);
test_not_loaded(
"./resources/log.js?pipe=sub&name=BadHashWithNoImport",
"Script with no import definition was not loaded, as it failed its integrity check"
);
test_not_loaded(
"bare",
"Bare specifier script was not loaded, as it failed its integrity check"
);
test_loaded(
"bare2",
["log:F"],
"Bare specifier used for integrity loaded, as its definition should have used the URL"
);
test_loaded(
"./resources/log.js?pipe=sub&name=InvalidExtra",
["log:InvalidExtra"],
"script was loaded, as its integrity check passed, despite having an extra invalid hash"
);
test_loaded(
"./resources/log.js?pipe=sub&name=Suffix",
["log:Suffix"],
"script was loaded, as its integrity check passed, despite having an invalid suffix"
);
test_loaded(
"./resources/log.js?pipe=sub&name=Multiple",
["log:Multiple"],
"script was loaded, as its integrity check passed given multiple hashes. This also makes sure that the larger hash is picked"
);
test_loaded(
"./resources/log.js?pipe=sub&name=Bare",
["log:Bare"],
"script was loaded, as its integrity check was ignored, as it was defined using a URL that looks like a bare specifier"
);
promise_test(async () => {
log = [];
const img = new Image();
const promise = new Promise((resolve, reject) => {
img.onload = () => {
import('./resources/log.js?pipe=sub&name=EventHandlerPass').then(resolve).catch(reject);
};
img.src = "/images/green.png?1";
});
await promise;
assert_equals(log.length, 1);
assert_equals(log[0], "log:EventHandlerPass");
}, "Script imported inside an event handler was loaded as its valid integrity check passed");
promise_test(async t => {
log = [];
const img = new Image();
const promise = new Promise((resolve, reject) => {
img.onload = () => {
import('./resources/log.js?pipe=sub&name=EventHandlerFail').then(resolve).catch(reject);
};
img.src = "/images/green.png?2";
});
await promise_rejects_js(t, TypeError, promise);
}, "Script imported inside an event handler was not loaded as its integrity check failed");
</script>