[Content Extensions] Add a way to match a domain but not subdomains
authorachristensen@apple.com <achristensen@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 26 Jun 2015 00:57:25 +0000 (00:57 +0000)
committerachristensen@apple.com <achristensen@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 26 Jun 2015 00:57:25 +0000 (00:57 +0000)
https://bugs.webkit.org/show_bug.cgi?id=146241
rdar://problem/21557754

Reviewed by Darin Adler.

Source/WebCore:

This patch makes it possible to have a trigger with an if-domain apply to sub2.sub1.webkit.org
but not sub1.webkit.org by making the domains default to only applying to the domain and not subdomains.
To make a domain apply to a domain and any subdomains, the domain must begin with a '*'.

* contentextensions/CombinedURLFilters.cpp:
(WebCore::ContentExtensions::CombinedURLFilters::addDomain):
(WebCore::ContentExtensions::CombinedURLFilters::addPattern):
Make domains apply only to the exact domain unless there is a * at the beginning,
in which case they apply to the domain and any subdomains.

Tools:

* TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp:
(TestWebKitAPI::TEST_F):
Update subdomain test because of changed behavior and add test for new '*' functionality.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@185973 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/contentextensions/CombinedURLFilters.cpp
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp

index 5eb097e..4e95ec5 100644 (file)
@@ -1,3 +1,21 @@
+2015-06-25  Alex Christensen  <achristensen@webkit.org>
+
+        [Content Extensions] Add a way to match a domain but not subdomains
+        https://bugs.webkit.org/show_bug.cgi?id=146241
+        rdar://problem/21557754
+
+        Reviewed by Darin Adler.
+
+        This patch makes it possible to have a trigger with an if-domain apply to sub2.sub1.webkit.org
+        but not sub1.webkit.org by making the domains default to only applying to the domain and not subdomains.
+        To make a domain apply to a domain and any subdomains, the domain must begin with a '*'.
+
+        * contentextensions/CombinedURLFilters.cpp:
+        (WebCore::ContentExtensions::CombinedURLFilters::addDomain):
+        (WebCore::ContentExtensions::CombinedURLFilters::addPattern):
+        Make domains apply only to the exact domain unless there is a * at the beginning,
+        in which case they apply to the domain and any subdomains.
+
 2015-06-25  Simon Fraser  <simon.fraser@apple.com>
 
         [iOS WK2] Swiping back just after scrolling can cause some tiles to disappear
index 722ad35..c13d775 100644 (file)
@@ -122,31 +122,44 @@ bool CombinedURLFilters::isEmpty() const
 
 void CombinedURLFilters::addDomain(uint64_t actionId, const String& domain)
 {
-    // This is like adding (.|^)domain$ by adding two Vector<Term>'s,
-    // but interpreting domain as a series of characters, not a regular expression.
-    // This way a domain of "webkit.org" will match "bugs.webkit.org" and "webkit.org".
-    // FIXME: Add support for matching only subdomains or no subdomains.
-    Vector<Term> prependDot;
-    Vector<Term> prependBeginningOfLine;
-    prependDot.reserveInitialCapacity(domain.length() + 3);
-    prependBeginningOfLine.reserveInitialCapacity(domain.length() + 1); // This is just no .* at the beginning.
-    
-    Term canonicalDotStar(Term::UniversalTransition);
-    canonicalDotStar.quantify(AtomQuantifier::ZeroOrMore);
-    prependDot.uncheckedAppend(canonicalDotStar);
-    prependDot.uncheckedAppend(Term('.', true));
-    
-    for (unsigned i = 0; i < domain.length(); i++) {
-        ASSERT(isASCII(domain[i]));
-        ASSERT(!isASCIIUpper(domain[i]));
-        prependDot.uncheckedAppend(Term(domain[i], true));
-        prependBeginningOfLine.uncheckedAppend(Term(domain[i], true));
+    unsigned domainLength = domain.length();
+    if (domainLength && domain[0] == '*') {
+        // If domain starts with a '*' then it means match domain and its subdomains, like (^|.)domain$
+        // This way a domain of "*webkit.org" will match "bugs.webkit.org" and "webkit.org".
+        Vector<Term> prependDot;
+        Vector<Term> prependBeginningOfLine;
+        prependDot.reserveInitialCapacity(domainLength + 2);
+        prependBeginningOfLine.reserveInitialCapacity(domainLength); // This is just no .* at the beginning.
+        
+        Term canonicalDotStar(Term::UniversalTransition);
+        canonicalDotStar.quantify(AtomQuantifier::ZeroOrMore);
+        prependDot.uncheckedAppend(canonicalDotStar);
+        prependDot.uncheckedAppend(Term('.', true));
+        
+        for (unsigned i = 1; i < domainLength; i++) {
+            ASSERT(isASCII(domain[i]));
+            ASSERT(!isASCIIUpper(domain[i]));
+            prependDot.uncheckedAppend(Term(domain[i], true));
+            prependBeginningOfLine.uncheckedAppend(Term(domain[i], true));
+        }
+        prependDot.uncheckedAppend(Term::EndOfLineAssertionTerm);
+        prependBeginningOfLine.uncheckedAppend(Term::EndOfLineAssertionTerm);
+        
+        addPattern(actionId, prependDot);
+        addPattern(actionId, prependBeginningOfLine);
+    } else {
+        // This is like adding ^domain$, but interpreting domain as a series of characters, not a regular expression.
+        // "webkit.org" will match "webkit.org" but not "bugs.webkit.org".
+        Vector<Term> prependBeginningOfLine;
+        prependBeginningOfLine.reserveInitialCapacity(domainLength + 1); // This is just no .* at the beginning.
+        for (unsigned i = 0; i < domainLength; i++) {
+            ASSERT(isASCII(domain[i]));
+            ASSERT(!isASCIIUpper(domain[i]));
+            prependBeginningOfLine.uncheckedAppend(Term(domain[i], true));
+        }
+        prependBeginningOfLine.uncheckedAppend(Term::EndOfLineAssertionTerm);
+        addPattern(actionId, prependBeginningOfLine);
     }
-    prependDot.uncheckedAppend(Term::EndOfLineAssertionTerm);
-    prependBeginningOfLine.uncheckedAppend(Term::EndOfLineAssertionTerm);
-    
-    addPattern(actionId, prependDot);
-    addPattern(actionId, prependBeginningOfLine);
 }
 
 void CombinedURLFilters::addPattern(uint64_t actionId, const Vector<Term>& pattern)
index bc27142..702055e 100644 (file)
@@ -1,3 +1,15 @@
+2015-06-25  Alex Christensen  <achristensen@webkit.org>
+
+        [Content Extensions] Add a way to match a domain but not subdomains
+        https://bugs.webkit.org/show_bug.cgi?id=146241
+        rdar://problem/21557754
+
+        Reviewed by Darin Adler.
+
+        * TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp:
+        (TestWebKitAPI::TEST_F):
+        Update subdomain test because of changed behavior and add test for new '*' functionality.
+
 2015-06-25  Jaehun Lim  <ljaehun.lim@samsung.com>
 
         Cleanup ENABLE_CSS3_CONDITIONAL_RULES codes.
index da677eb..9b3797f 100644 (file)
@@ -408,7 +408,8 @@ TEST_F(ContentExtensionTest, DomainTriggers)
     testRequest(ifDomainBackend, mainDocumentRequest("http://webkit.org/test.htm"), { });
     testRequest(ifDomainBackend, mainDocumentRequest("http://bugs.webkit.org/test.htm"), { });
     testRequest(ifDomainBackend, mainDocumentRequest("http://webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad });
-    testRequest(ifDomainBackend, mainDocumentRequest("http://bugs.webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad });
+    testRequest(ifDomainBackend, mainDocumentRequest("http://bugs.webkit.org/test.html"), { });
+    testRequest(ifDomainBackend, mainDocumentRequest("http://sub2.sub1.webkit.org/test.html"), { });
     testRequest(ifDomainBackend, mainDocumentRequest("http://not_webkit.org/test.htm"), { });
     testRequest(ifDomainBackend, mainDocumentRequest("http://webkit.organization/test.htm"), { });
     testRequest(ifDomainBackend, mainDocumentRequest("http://not_webkit.org/test.html"), { });
@@ -418,11 +419,58 @@ TEST_F(ContentExtensionTest, DomainTriggers)
     testRequest(unlessDomainBackend, mainDocumentRequest("http://webkit.org/test.htm"), { });
     testRequest(unlessDomainBackend, mainDocumentRequest("http://bugs.webkit.org/test.htm"), { });
     testRequest(unlessDomainBackend, mainDocumentRequest("http://webkit.org/test.html"), { });
-    testRequest(unlessDomainBackend, mainDocumentRequest("http://bugs.webkit.org/test.html"), { });
+    testRequest(unlessDomainBackend, mainDocumentRequest("http://bugs.webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad });
+    testRequest(unlessDomainBackend, mainDocumentRequest("http://sub2.sub1.webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad });
     testRequest(unlessDomainBackend, mainDocumentRequest("http://not_webkit.org/test.htm"), { });
     testRequest(unlessDomainBackend, mainDocumentRequest("http://webkit.organization/test.htm"), { });
     testRequest(unlessDomainBackend, mainDocumentRequest("http://not_webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad });
     testRequest(unlessDomainBackend, mainDocumentRequest("http://webkit.organization/test.html"), { ContentExtensions::ActionType::BlockLoad });
+    
+    auto ifDomainStarBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"test\\\\.html\", \"if-domain\":[\"*webkit.org\"]}}]");
+    testRequest(ifDomainStarBackend, mainDocumentRequest("http://webkit.org/test.htm"), { });
+    testRequest(ifDomainStarBackend, mainDocumentRequest("http://bugs.webkit.org/test.htm"), { });
+    testRequest(ifDomainStarBackend, mainDocumentRequest("http://webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad });
+    testRequest(ifDomainStarBackend, mainDocumentRequest("http://bugs.webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad });
+    testRequest(ifDomainStarBackend, mainDocumentRequest("http://sub2.sub1.webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad });
+    testRequest(ifDomainStarBackend, mainDocumentRequest("http://not_webkit.org/test.htm"), { });
+    testRequest(ifDomainStarBackend, mainDocumentRequest("http://webkit.organization/test.htm"), { });
+    testRequest(ifDomainStarBackend, mainDocumentRequest("http://not_webkit.org/test.html"), { });
+    testRequest(ifDomainStarBackend, mainDocumentRequest("http://webkit.organization/test.html"), { });
+    
+    auto unlessDomainStarBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"test\\\\.html\", \"unless-domain\":[\"*webkit.org\"]}}]");
+    testRequest(unlessDomainStarBackend, mainDocumentRequest("http://webkit.org/test.htm"), { });
+    testRequest(unlessDomainStarBackend, mainDocumentRequest("http://bugs.webkit.org/test.htm"), { });
+    testRequest(unlessDomainStarBackend, mainDocumentRequest("http://webkit.org/test.html"), { });
+    testRequest(unlessDomainStarBackend, mainDocumentRequest("http://bugs.webkit.org/test.html"), { });
+    testRequest(unlessDomainStarBackend, mainDocumentRequest("http://sub2.sub1.webkit.org/test.html"), { });
+    testRequest(unlessDomainStarBackend, mainDocumentRequest("http://not_webkit.org/test.htm"), { });
+    testRequest(unlessDomainStarBackend, mainDocumentRequest("http://webkit.organization/test.htm"), { });
+    testRequest(unlessDomainStarBackend, mainDocumentRequest("http://not_webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad });
+    testRequest(unlessDomainStarBackend, mainDocumentRequest("http://webkit.organization/test.html"), { ContentExtensions::ActionType::BlockLoad });
+
+    auto ifSubDomainBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"test\\\\.html\", \"if-domain\":[\"sub1.webkit.org\"]}}]");
+    testRequest(ifSubDomainBackend, mainDocumentRequest("http://webkit.org/test.html"), { });
+    testRequest(ifSubDomainBackend, mainDocumentRequest("http://bugs.webkit.org/test.html"), { });
+    testRequest(ifSubDomainBackend, mainDocumentRequest("http://sub1.webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad });
+    testRequest(ifSubDomainBackend, mainDocumentRequest("http://sub2.sub1.webkit.org/test.html"), { });
+
+    auto ifSubDomainStarBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"test\\\\.html\", \"if-domain\":[\"*sub1.webkit.org\"]}}]");
+    testRequest(ifSubDomainStarBackend, mainDocumentRequest("http://webkit.org/test.html"), { });
+    testRequest(ifSubDomainStarBackend, mainDocumentRequest("http://bugs.webkit.org/test.html"), { });
+    testRequest(ifSubDomainStarBackend, mainDocumentRequest("http://sub1.webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad });
+    testRequest(ifSubDomainStarBackend, mainDocumentRequest("http://sub2.sub1.webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad });
+
+    auto unlessSubDomainBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"test\\\\.html\", \"unless-domain\":[\"sub1.webkit.org\"]}}]");
+    testRequest(unlessSubDomainBackend, mainDocumentRequest("http://webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad });
+    testRequest(unlessSubDomainBackend, mainDocumentRequest("http://bugs.webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad });
+    testRequest(unlessSubDomainBackend, mainDocumentRequest("http://sub1.webkit.org/test.html"), { });
+    testRequest(unlessSubDomainBackend, mainDocumentRequest("http://sub2.sub1.webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad });
+    
+    auto unlessSubDomainStarBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"test\\\\.html\", \"unless-domain\":[\"*sub1.webkit.org\"]}}]");
+    testRequest(unlessSubDomainStarBackend, mainDocumentRequest("http://webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad });
+    testRequest(unlessSubDomainStarBackend, mainDocumentRequest("http://bugs.webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad });
+    testRequest(unlessSubDomainStarBackend, mainDocumentRequest("http://sub1.webkit.org/test.html"), { });
+    testRequest(unlessSubDomainStarBackend, mainDocumentRequest("http://sub2.sub1.webkit.org/test.html"), { });
 
     auto combinedBackend1 = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"test_block_load\", \"if-domain\":[\"webkit.org\"]}},"
         "{\"action\":{\"type\":\"block-cookies\"},\"trigger\":{\"url-filter\":\"test_block_cookies\", \"unless-domain\":[\"webkit.org\"]}}]");