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