1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
<!DOCTYPE html>
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<script>
const blank = 'about:blank';
const dangling_url = 'resources/empty.html?\n<';
const navigation_api_calls = [
`window.open(\`${dangling_url}\`,'_self')`,
`location.replace(\`${dangling_url}\`)`,
];
function get_requests(worker, expected) {
return new Promise(resolve => {
navigator.serviceWorker.addEventListener('message', function onMsg(evt) {
if (evt.data.size >= expected) {
navigator.serviceWorker.removeEventListener('message', onMsg);
resolve(evt.data);
} else {
worker.postMessage("");
}
});
worker.postMessage("");
});
}
navigation_api_calls.forEach(call => {
async_test(t => {
const iframe =
document.body.appendChild(document.createElement('iframe'));
t.step(() => {
iframe.contentWindow.eval(call);
t.step_timeout(() => {
assert_false(iframe.contentWindow.location.href.endsWith(blank));
t.done();
}, 500);
});
}, `Does not block ${call}`);
});
const dangling_resource = "404?type=text/javascript&\n<"
const api_calls = [
[`const xhr = new XMLHttpRequest();
xhr.open("GET", \`${"xhr" + dangling_resource}\`);
xhr.send(null);`, "xhr"],
[`new EventSource(\`${"EventSource" + dangling_resource}\`)`,"EventSource"],
[`fetch(\`${"fetch" + dangling_resource}\`).catch(()=>{})`, "fetch"],
[`new Worker(\`${"Worker" + dangling_resource}\`)`, "Worker"],
[`let text = \`try{importScripts(\\\`${location.href + "/../importScripts" + dangling_resource}\\\`)}catch(e){}\`;
let blob = new Blob([text], {type : 'text/javascript'});
let url = URL.createObjectURL(blob);
new Worker(url)`, "importScripts"],
];
navigator.serviceWorker.register('service-worker.js');
const iframe = document.createElement('iframe');
iframe.src = "resources/empty.html";
document.body.appendChild(iframe);
api_calls.forEach(call => {
promise_test(t => {
return new Promise(resolve => {
navigator.serviceWorker.ready.then(t.step_func(registration => {
iframe.contentWindow.eval(call[0]);
get_requests(registration.active, 0).then(t.step_func(requests => {
resolve(assert_true(requests.has(call[1] + dangling_resource)));
}));
}));
});
}, `Does not block ${call[1]}`);
});
async_test(t => {
let url = new URL(location.origin + "/" + dangling_url);
// Newlines are removed by the URL parser.
assert_true(url.href.endsWith(encodeURI(dangling_url.replace("\n",""))));
t.done();
}, `Does not block new URL()`);
</script>
|