testharness-helper.sub.js (5546B)
1 const Host = { 2 SAME_ORIGIN: "same-origin", 3 CROSS_ORIGIN: "cross-origin", 4 }; 5 6 const PolicyHeader = { 7 CSP: "echo-policy.py?policy=", 8 CSP_MULTIPLE: "echo-policy-multiple.py", 9 REQUIRED_CSP: "echo-required-csp.py", 10 ALLOW_CSP_FROM: "echo-allow-csp-from.py", 11 }; 12 13 const IframeLoad = { 14 EXPECT_BLOCK: true, 15 EXPECT_LOAD: false, 16 }; 17 18 function getOrigin() { 19 var url = new URL("http://{{host}}:{{ports[http][0]}}/"); 20 return url.origin; 21 } 22 23 function getCrossOrigin() { 24 var url = new URL("http://{{domains[天気の良い日]}}:{{ports[http][0]}}/"); 25 return url.toString(); 26 } 27 28 function getSecureCrossOrigin() { 29 // Since wptserve spins up servers on non-default port, 'self' matches 30 // http://[host]:[specified-port] and https://[host]:[specified-port], but not 31 // https://[host]:[https-port]. So, we use the http port for this https origin 32 // in order to verify that a secure variant of a non-secure URL matches 'self'. 33 var url = new URL("https://{{domains[天気の良い日]}}:{{ports[http][0]}}"); 34 return url.toString(); 35 } 36 37 function generateURL(host, path, include_second_level_iframe, second_level_iframe_csp) { 38 var url = new URL("http://{{host}}:{{ports[http][0]}}/content-security-policy/embedded-enforcement/support/"); 39 url.hostname = host == Host.SAME_ORIGIN ? "{{host}}" : "{{domains[天気の良い日]}}"; 40 url.pathname += path; 41 if (include_second_level_iframe) { 42 url.searchParams.append("include_second_level_iframe", ""); 43 if (second_level_iframe_csp) 44 url.searchParams.append("second_level_iframe_csp", second_level_iframe_csp); 45 } 46 47 return url; 48 } 49 50 function generateURLString(host, path) { 51 return generateURL(host, path, false, "").toString(); 52 } 53 54 function generateURLStringWithSecondIframeParams(host, path, second_level_iframe_csp) { 55 return generateURL(host, path, true, second_level_iframe_csp).toString(); 56 } 57 58 function generateRedirect(host, target) { 59 var url = new URL("http://{{host}}:{{ports[http][0]}}/common/redirect.py?location=" + 60 encodeURIComponent(target)); 61 url.hostname = host == Host.SAME_ORIGIN ? "{{host}}" : "{{domains[天気の良い日]}}"; 62 63 return url.toString(); 64 } 65 66 function generateUrlWithPolicies(host, policy) { 67 var url = generateURL(host, PolicyHeader.CSP_MULTIPLE); 68 if (policy != null) 69 url.searchParams.append("policy", policy); 70 return url; 71 } 72 73 function generateUrlWithAllowCSPFrom(host, allowCspFrom) { 74 var url = generateURL(host, PolicyHeader.ALLOW_CSP_FROM); 75 if (allowCspFrom != null) 76 url.searchParams.append("allow_csp_from", allowCspFrom); 77 return url; 78 } 79 80 function assert_required_csp(t, url, csp, expected) { 81 var i = document.createElement('iframe'); 82 if(csp) 83 i.csp = csp; 84 i.src = url; 85 86 window.addEventListener('message', t.step_func(e => { 87 if (e.source != i.contentWindow || !('required_csp' in e.data)) 88 return; 89 90 if (expected.indexOf(e.data['required_csp']) == -1) 91 assert_unreached('Child iframes have unexpected csp:"' + e.data['required_csp'] + '"'); 92 93 expected.splice(expected.indexOf(e.data['required_csp']), 1); 94 95 if (e.data['test_header_injection'] != null) 96 assert_unreached('HTTP header injection was successful'); 97 98 if (expected.length == 0) 99 t.done(); 100 })); 101 102 document.body.appendChild(i); 103 } 104 105 function assert_iframe_with_csp(t, url, csp, shouldBlock, urlId, blockedURI, 106 checkImageLoaded) { 107 const i = document.createElement('iframe'); 108 url.searchParams.append("id", urlId); 109 i.src = url.toString(); 110 if (csp != null) 111 i.csp = csp; 112 113 if (shouldBlock) { 114 // Assert iframe does not load and is inaccessible. 115 window.addEventListener("message", t.step_func(function(e) { 116 if (e.source != i.contentWindow) return; 117 assert_unreached('No message should be sent from the frame.'); 118 })); 119 i.onload = t.step_wait_func_done(function() { 120 if (!i.contentWindow) return false; 121 try { 122 let x = i.contentWindow.location.href; 123 return false; 124 } catch (e) { 125 return true; 126 } 127 }, t.step_func(() => { 128 assert_throws_dom("SecurityError", () => { 129 let x = i.contentWindow.location.href; 130 }); 131 }), "The error frame should be cross-origin.", 5000, 500); 132 } else { 133 let successPromises = []; 134 135 let loadPromise = new Promise(resolve => { 136 i.onload = resolve; 137 }); 138 successPromises.push(loadPromise); 139 140 let loadMsgPromise = new Promise(resolve => { 141 window.addEventListener("message", function (e) { 142 if (e.source != i.contentWindow) return; 143 if (e.data["loaded"] && e.data["id"] === urlId) resolve(); 144 }); 145 }); 146 successPromises.push(loadMsgPromise); 147 148 if (blockedURI) { 149 let securityViolationPromise = new Promise(resolve => { 150 window.addEventListener('message', t.step_func(e => { 151 if (e.source != i.contentWindow) return; 152 if (!e.data.securitypolicyviolation) return; 153 assert_equals(e.data["blockedURI"], blockedURI); 154 resolve(); 155 })); 156 }); 157 successPromises.push(securityViolationPromise); 158 } 159 160 if (checkImageLoaded) { 161 let imageLoadedPromise = new Promise(resolve => { 162 window.addEventListener('message', e => { 163 if (e.source != i.contentWindow) return; 164 if (e.data === "img loaded") resolve(); 165 }); 166 }); 167 successPromises.push(imageLoadedPromise); 168 } 169 170 // Wait for all promises to resolve. 171 Promise.all(successPromises).then(t.step_func_done()); 172 } 173 document.body.appendChild(i); 174 }