Bug 1318664 - fix about pages linking to themselves with query parameters, r=bz a=jcristau
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Wed, 23 Nov 2016 18:26:44 +0000
changeset 352976 344a95f48dde41dd379da627041a3da06b972f5f
parent 352975 39a2b1903eb3691204ec071484f720ea26cda575
child 352977 ab8259a79df2c940551ae3e7a4b9c57e38623633
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz, jcristau
bugs1318664
milestone52.0a2
Bug 1318664 - fix about pages linking to themselves with query parameters, r=bz a=jcristau MozReview-Commit-ID: Dsqj0L4aIlv
caps/nsScriptSecurityManager.cpp
caps/tests/mochitest/browser_checkloaduri.js
--- a/caps/nsScriptSecurityManager.cpp
+++ b/caps/nsScriptSecurityManager.cpp
@@ -812,26 +812,37 @@ nsScriptSecurityManager::CheckLoadURIWit
                              &denySameSchemeLinks);
     if (NS_FAILED(rv)) return rv;
 
     while (currentURI && currentOtherURI) {
         nsAutoCString scheme, otherScheme;
         currentURI->GetScheme(scheme);
         currentOtherURI->GetScheme(otherScheme);
 
+        bool schemesMatch = scheme.Equals(otherScheme, stringComparator);
+        bool isSamePage;
+        // about: URIs are special snowflakes.
+        if (scheme.EqualsLiteral("about")) {
+            nsAutoCString module, otherModule;
+            isSamePage = schemesMatch &&
+                NS_SUCCEEDED(NS_GetAboutModuleName(currentURI, module)) &&
+                NS_SUCCEEDED(NS_GetAboutModuleName(currentOtherURI, otherModule)) &&
+                module.Equals(otherModule);
+        } else {
+            bool equalExceptRef = false;
+            rv = currentURI->EqualsExceptRef(currentOtherURI, &equalExceptRef);
+            isSamePage = NS_SUCCEEDED(rv) && equalExceptRef;
+        }
+
         // If schemes are not equal, or they're equal but the target URI
         // is different from the source URI and doesn't always allow linking
         // from the same scheme, check if the URI flags of the current target
         // URI allow the current source URI to link to it.
         // The policy is specified by the protocol flags on both URIs.
-        bool equalExceptRef = false;
-        if (!scheme.Equals(otherScheme, stringComparator) ||
-            (denySameSchemeLinks &&
-             (!NS_SUCCEEDED(currentURI->EqualsExceptRef(currentOtherURI, &equalExceptRef)) ||
-              !equalExceptRef))) {
+        if (!schemesMatch || (denySameSchemeLinks && !isSamePage)) {
             return CheckLoadURIFlags(currentURI, currentOtherURI,
                                      sourceBaseURI, targetBaseURI, aFlags);
         }
         // Otherwise... check if we can nest another level:
         nsCOMPtr<nsINestedURI> nestedURI = do_QueryInterface(currentURI);
         nsCOMPtr<nsINestedURI> nestedOtherURI = do_QueryInterface(currentOtherURI);
 
         // If schemes match and neither URI is nested further, we're OK.
--- a/caps/tests/mochitest/browser_checkloaduri.js
+++ b/caps/tests/mochitest/browser_checkloaduri.js
@@ -47,16 +47,28 @@ const URLs = new Map([
     ["view-source:http://www.example2.com", true, true, true],
     ["view-source:https://www.example2.com", true, true, true],
     ["view-source:feed:http://www.example2.com", false, false, true],
     ["feed:view-source:http://www.example2.com", false, false, false],
     ["data:text/html,Hi", true, false, true],
     ["view-source:data:text/html,Hi", true, false, true],
     ["javascript:alert('hi')", true, false, true],
   ]],
+  ["about:foo", [
+    ["about:foo?", true, true, true],
+    ["about:foo?bar", true, true, true],
+    ["about:foo#", true, true, true],
+    ["about:foo#bar", true, true, true],
+    ["about:foo?#", true, true, true],
+    ["about:foo?bar#baz", true, true, true],
+    ["about:bar", false, false, true],
+    ["about:bar?foo#baz", false, false, true],
+    ["about:bar?foo", false, false, true],
+    ["http://www.example.com/", true, true, true],
+  ]],
 ]);
 
 function testURL(source, target, canLoad, canLoadWithoutInherit, canCreate, flags) {
   let threw = false;
   let targetURI;
   try {
     targetURI = makeURI(target);
   } catch (ex) {