Bug 1280370 - Don't set MatchPattern::mMatchSubdomain if the scheme does not support hosts draft
authorRob Wu <rob@robwu.nl>
Tue, 24 Jul 2018 13:33:15 +0200
changeset 827663 3f03af6235584023e6ee4207af62a792f9efd05a
parent 827662 0f4d7bef821a485f5bc9888a258ffc0dc4f99c08
child 827664 804b1238dc0acf3960f574fd013bdfcb20fc12e2
child 827704 6546660bd7b6c4b23fdbb53a11c656d1aed0cbd3
push id118555
push userbmo:rob@robwu.nl
push dateWed, 08 Aug 2018 16:39:15 +0000
bugs1280370
milestone63.0a1
Bug 1280370 - Don't set MatchPattern::mMatchSubdomain if the scheme does not support hosts Otherwise MatchPattern::Matches would always return false if the aExplicit flag is set to true, even if the match pattern is identical to the tested URL. MozReview-Commit-ID: FtdOgwrAkk8
toolkit/components/extensions/MatchPattern.cpp
toolkit/components/extensions/test/xpcshell/test_MatchPattern.js
--- a/toolkit/components/extensions/MatchPattern.cpp
+++ b/toolkit/components/extensions/MatchPattern.cpp
@@ -323,19 +323,17 @@ MatchPattern::Init(JSContext* aCx, const
 
   /***************************************************************************
    * Host
    ***************************************************************************/
   offset = index + 1;
   tail.Rebind(aPattern, offset);
 
   if (scheme == nsGkAtoms::about || scheme == nsGkAtoms::data) {
-    // about: and data: URIs don't have hosts, so just treat the host as a
-    // wildcard and match on the path.
-    mMatchSubdomain = true;
+    // about: and data: URIs don't have hosts, so just match on the path.
     // And so, ignorePath doesn't make sense for these matchers.
     aIgnorePath = false;
   } else {
     if (!StringHead(tail, 2).EqualsLiteral("//")) {
       aRv.Throw(NS_ERROR_INVALID_ARG);
       return;
     }
 
--- a/toolkit/components/extensions/test/xpcshell/test_MatchPattern.js
+++ b/toolkit/components/extensions/test/xpcshell/test_MatchPattern.js
@@ -1,45 +1,45 @@
 /* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set sts=2 sw=2 et tw=80: */
 "use strict";
 
 add_task(async function test_MatchPattern_matches() {
-  function test(url, pattern, normalized = pattern, options = {}) {
+  function test(url, pattern, normalized = pattern, options = {}, explicit) {
     let uri = Services.io.newURI(url);
 
     pattern = Array.concat(pattern);
     normalized = Array.concat(normalized);
 
     let patterns = pattern.map(pat => new MatchPattern(pat, options));
 
     let set = new MatchPatternSet(pattern, options);
     let set2 = new MatchPatternSet(patterns, options);
 
     deepEqual(set2.patterns, patterns, "Patterns in set should equal the input patterns");
 
-    equal(set.matches(uri), set2.matches(uri), "Single pattern and pattern set should return the same match");
+    equal(set.matches(uri, explicit), set2.matches(uri, explicit), "Single pattern and pattern set should return the same match");
 
     for (let [i, pat] of patterns.entries()) {
       equal(pat.pattern, normalized[i], "Pattern property should contain correct normalized pattern value");
     }
 
     if (patterns.length == 1) {
-      equal(patterns[0].matches(uri), set.matches(uri), "Single pattern and string set should return the same match");
+      equal(patterns[0].matches(uri, explicit), set.matches(uri, explicit), "Single pattern and string set should return the same match");
     }
 
-    return set.matches(uri);
+    return set.matches(uri, explicit);
   }
 
-  function pass({url, pattern, normalized, options}) {
-    ok(test(url, pattern, normalized, options), `Expected match: ${JSON.stringify(pattern)}, ${url}`);
+  function pass({url, pattern, normalized, options, explicit}) {
+    ok(test(url, pattern, normalized, options, explicit), `Expected match: ${JSON.stringify(pattern)}, ${url}`);
   }
 
-  function fail({url, pattern, normalized, options}) {
-    ok(!test(url, pattern, normalized, options), `Expected no match: ${JSON.stringify(pattern)}, ${url}`);
+  function fail({url, pattern, normalized, options, explicit}) {
+    ok(!test(url, pattern, normalized, options, explicit), `Expected no match: ${JSON.stringify(pattern)}, ${url}`);
   }
 
   function invalid({pattern}) {
     Assert.throws(() => new MatchPattern(pattern), /.*/,
                   `Invalid pattern '${pattern}' should throw`);
     Assert.throws(() => new MatchPatternSet([pattern]), /.*/,
                   `Invalid pattern '${pattern}' should throw`);
   }
@@ -129,16 +129,22 @@ add_task(async function test_MatchPatter
 
   pass({url: "resource://foo/bar", pattern: ["resource://foo/bar"], options: {restrictSchemes: false}});
   fail({url: "resource://fog/bar", pattern: ["resource://foo/bar"], options: {restrictSchemes: false}});
   fail({url: "about:foo", pattern: ["about:meh"], options: {restrictSchemes: false}});
 
   // Matchers for schemes without host should ignore ignorePath.
   pass({url: "about:reader?http://e.com/", pattern: ["about:reader*"], options: {ignorePath: true, restrictSchemes: false}});
   pass({url: "data:,", pattern: ["data:,*"], options: {ignorePath: true}});
+
+  // Matchers for schems without host should still match even if the explicit (host) flag is set.
+  pass({url: "about:reader?explicit", pattern: ["about:reader*"], options: {restrictSchemes: false}, explicit: true});
+  pass({url: "about:reader?explicit", pattern: ["about:reader?explicit"], options: {restrictSchemes: false}, explicit: true});
+  pass({url: "data:,explicit", pattern: ["data:,explicit"], explicit: true});
+  pass({url: "data:,explicit", pattern: ["data:,*"], explicit: true});
 });
 
 add_task(async function test_MatchPattern_overlaps() {
   function test(filter, hosts, optional) {
     filter = Array.concat(filter);
     hosts = Array.concat(hosts);
     optional = Array.concat(optional);