summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/referrer-policy/generic/test-case.sub.js
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/referrer-policy/generic/test-case.sub.js')
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/test-case.sub.js127
1 files changed, 127 insertions, 0 deletions
diff --git a/testing/web-platform/tests/referrer-policy/generic/test-case.sub.js b/testing/web-platform/tests/referrer-policy/generic/test-case.sub.js
new file mode 100644
index 0000000000..717cd1a5e7
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/test-case.sub.js
@@ -0,0 +1,127 @@
+// https://w3c.github.io/webappsec-referrer-policy/#strip-url
+function stripUrlForUseAsReferrer(url, originOnly) {
+ // Step 2. If url’s scheme is a local scheme, then return no referrer.
+ const parsedUrl = new URL(url);
+
+ if (["about:", "blob:", "data:"].includes(parsedUrl.protocol))
+ return undefined;
+
+ // Step 3. Set url’s username to the empty string.
+ parsedUrl.username = '';
+
+ // Step 4. Set url’s password to null.
+ parsedUrl.password = '';
+
+ // Step 5. Set url’s fragment to null.
+ parsedUrl.hash = '';
+
+ // Step 6. If the origin-only flag is true, then:
+ if (originOnly) {
+ // Step 6.1. Set url’s path to null.
+ parsedUrl.pathname = '';
+ // Step 6.2. Set url’s query to null.
+ parsedUrl.search = '';
+ }
+ return parsedUrl.href;
+}
+
+function invokeScenario(scenario) {
+ const urls = getRequestURLs(
+ scenario.subresource,
+ scenario.origin,
+ scenario.redirection);
+ /** @type {Subresource} */
+ const subresource = {
+ subresourceType: scenario.subresource,
+ url: urls.testUrl,
+ policyDeliveries: scenario.subresource_policy_deliveries,
+ };
+
+ return invokeRequest(subresource, scenario.source_context_list);
+}
+
+const referrerUrlResolver = {
+ // The spec allows UAs to "enforce arbitrary policy considerations in the
+ // interests of minimizing data leakage"; to start to vaguely approximate
+ // this, we allow stronger policies to be used instead of what's specificed.
+ "omitted": function(sourceUrl) {
+ return [undefined];
+ },
+ "origin": function(sourceUrl) {
+ return [stripUrlForUseAsReferrer(sourceUrl, true),
+ undefined];
+ },
+ "stripped-referrer": function(sourceUrl) {
+ return [stripUrlForUseAsReferrer(sourceUrl, false),
+ stripUrlForUseAsReferrer(sourceUrl, true),
+ undefined];
+ }
+};
+
+function checkResult(scenario, expectation, result) {
+// https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer
+ let referrerSource = result.sourceContextUrl;
+ const sentFromSrcdoc = scenario.source_context_list.length > 0 &&
+ scenario.source_context_list[scenario.source_context_list.length - 1]
+ .sourceContextType === 'srcdoc';
+ if (sentFromSrcdoc) {
+ // Step 3. While document is an iframe srcdoc document, let document be
+ // document's browsing context's browsing context container's node
+ // document. [spec text]
+
+ // Workaround for srcdoc cases. Currently we only test <iframe srcdoc>
+ // inside the top-level Document, so |document| in the spec here is
+ // the top-level Document.
+ // This doesn't work if e.g. we test <iframe srcdoc> inside another
+ // external <iframe>.
+ referrerSource = location.toString();
+ }
+ const possibleReferrerUrls =
+ referrerUrlResolver[expectation](referrerSource);
+
+ // Check the reported URL.
+ assert_in_array(result.referrer,
+ possibleReferrerUrls,
+ "document.referrer");
+ assert_in_array(result.headers.referer,
+ possibleReferrerUrls,
+ "HTTP Referer header");
+}
+
+function runLengthTest(scenario, urlLength, expectation, testDescription) {
+ // `Referer` headers with length over 4k are culled down to an origin, so,
+ // let's test around that boundary for tests that would otherwise return
+ // the complete URL.
+ history.pushState(null, null, "/");
+ history.replaceState(null, null,
+ "A".repeat(urlLength - location.href.length));
+
+ promise_test(t => {
+ assert_equals(scenario.expectation, "stripped-referrer");
+ // Only on top-level Window, due to navigations using `history`.
+ assert_equals(scenario.source_context_list.length, 0);
+
+ return invokeScenario(scenario)
+ .then(result => checkResult(scenario, expectation, result));
+ }, testDescription);
+}
+
+function TestCase(scenarios, sanityChecker) {
+ function runTest(scenario) {
+ // This check is A NOOP in release.
+ sanityChecker.checkScenario(scenario);
+
+ promise_test(_ => {
+ return invokeScenario(scenario)
+ .then(result => checkResult(scenario, scenario.expectation, result));
+ }, scenario.test_description);
+ }
+
+ function runTests() {
+ for (const scenario of scenarios) {
+ runTest(scenario);
+ }
+ }
+
+ return {start: runTests};
+}