CSP: Do not strip non webby URL in reports.

In https://crbug.com/1264789, developers complained non HTTP/HTTPS URLs
are not included in reports.

The restriction was mostly introduced by:
https://codereview.chromium.org/2002943002 for convenience, in order to
reuse KURL::StrippedForUseAsReferrer.

The drawback is that "webpack://node_modules/sample/script4.js" is
transformed into "webpack", since its protocol is not http/https.

This patch initially wanted to remove this restrictions by rewriting our
own version of StrippedForUseAsReferrer, without the inconvenience, and
most importantly, add 14 WPT test cases.

Last minute, I wrote a specification:
https://github.com/w3c/webappsec-csp/pull/527 and decided to prefer
using an allow-list containing ['http', 'https'] instead of a
block-list. As a result, 'webpack:' URLs continue to be stripped down to
their scheme. Sorry...

Note: There are some scheme we don't want to expose, like
['chrome-extension', 'moz-extension'].

Bug: 1264789
Change-Id: Ia967c3122915a37b119321bb327e6c969d649020
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3263879
Commit-Queue: Arthur Sonzogni <arthursonzogni@chromium.org>
Reviewed-by: Mike West <mkwst@chromium.org>
Cr-Commit-Position: refs/heads/main@{#944975}
diff --git a/content-security-policy/securitypolicyviolation/blockeduri-ws-wss-scheme.html b/content-security-policy/securitypolicyviolation/blockeduri-ws-wss-scheme.html
index 1dd99f7..88bf4ae 100644
--- a/content-security-policy/securitypolicyviolation/blockeduri-ws-wss-scheme.html
+++ b/content-security-policy/securitypolicyviolation/blockeduri-ws-wss-scheme.html
@@ -23,28 +23,28 @@
 }, "Install <meta> CSP");
 
 promise_test(async test => {
-  const url = get_host_info().HTTP_ORIGIN.replace("http", "ws");
+  const url = get_host_info().HTTP_ORIGIN.replace("http", "ws") + "/path";
   const violation = nextCSPViolation(test);
   try { new WebSocket(url); } catch (e) {}
   assert_equals((await violation).blockedURI, url);
 }, "ws");
 
 promise_test(async test => {
-  const url = get_host_info().HTTP_ORIGIN.replace("http", "wss");
+  const url = get_host_info().HTTP_ORIGIN.replace("http", "wss") + "/path";
   const violation = nextCSPViolation(test);
   try { new WebSocket(url); } catch (e) {}
   assert_equals((await violation).blockedURI, url);
 }, "wss");
 
 promise_test(async test => {
-  const url = get_host_info().HTTP_REMOTE_ORIGIN.replace("http", "wss");
+  const url = get_host_info().HTTP_REMOTE_ORIGIN.replace("http", "wss") + "/path";
   const violation = nextCSPViolation(test);
   try { new WebSocket(url); } catch (e) {}
   assert_equals((await violation).blockedURI, url);
 }, "cross-origin");
 
 promise_test(async test => {
-  const url = get_host_info().HTTP_ORIGIN.replace("http", "wss");
+  const url = get_host_info().HTTP_ORIGIN.replace("http", "wss") + "/path";
   const violation = nextCSPViolation(test);
   try {new WebSocket(redirector + "?location=" + url); } catch (e) {}
   assert_equals((await violation).blockedURI, url);
diff --git a/content-security-policy/securitypolicyviolation/source-file.html b/content-security-policy/securitypolicyviolation/source-file.html
new file mode 100644
index 0000000..354b8df
--- /dev/null
+++ b/content-security-policy/securitypolicyviolation/source-file.html
@@ -0,0 +1,102 @@
+<meta http-equiv="Content-Security-Policy" content="require-trusted-types-for 'script';" />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+
+const policy = trustedTypes.createPolicy("sample", {createScript: x => x});
+
+// Check CSP violated by a script originating from |input| returns a CSP
+// violation whose sourceFile is |output|.
+const testSourceFile = (description, input, output) => {
+  promise_test(async test => {
+    // Listen for TrustedType violation.
+    const violation = new Promise(resolve => {
+      document.addEventListener("securitypolicyviolation", e => {
+        resolve(e);
+      }, {once: true});
+    });
+
+    // A trusted script using a customized sourceURL. The script's execution
+    // itself will trigger a TrustedType violation.
+    const trusted_script = policy.createScript(`
+      eval('');
+      //# sourceURL=${input}
+    `)
+    try {
+      eval(trusted_script);
+      assert_unreached();
+    } catch (e) {}
+
+    assert_equals((await violation).sourceFile, output);
+  }, description);
+};
+
+testSourceFile("Basic HTTPS URL",
+               "http://dummy.test/script1.js",
+               "http://dummy.test/script1.js");
+
+testSourceFile("Basic HTTP URL",
+               "https://dummy.test/script1.js",
+               "https://dummy.test/script1.js");
+
+testSourceFile("Basic WSS URL",
+               "wss://dummy.test/script1.js",
+               "wss://dummy.test/script1.js");
+
+testSourceFile("Basic WS URL",
+               "ws://dummy.test/script1.js",
+               "ws://dummy.test/script1.js");
+
+testSourceFile("Fragment",
+               "https://dummy.test/script1.js#frag",
+               "https://dummy.test/script1.js");
+
+testSourceFile("Query",
+               "https://dummy.test/script1.js?query",
+               "https://dummy.test/script1.js");
+
+testSourceFile("Port",
+               "https://dummy.test:8080/script1.js",
+               "https://dummy.test:8080/script1.js");
+
+testSourceFile("User:password",
+               "https://user:password@dummy.test/script1.js",
+               "https://dummy.test/script1.js");
+
+testSourceFile("User",
+               "https://user@dummy.test/script1.js",
+               "https://dummy.test/script1.js");
+
+testSourceFile("Invalid URL",
+               "script2.js",
+               "");
+
+testSourceFile("file:",
+               "file:///temp/script3.js",
+               "file");
+
+testSourceFile("Custom protocol",
+               "webpack://node_modules/sample/script4.js",
+               "webpack");
+
+testSourceFile("about:blank",
+               "about:blank",
+               "about");
+
+testSourceFile("about:custom",
+               "about:custom",
+               "about");
+
+testSourceFile("data:",
+               "data:text/html;charset=utf8,<html></html>",
+               "data");
+
+testSourceFile("blob:",
+               "blob:http://test.test/012345-6789-abcd-efab-0123456789",
+               "blob");
+
+testSourceFile("javascript:",
+               "javascript:void(0)",
+               "javascript");
+
+</script>