Title: [181932] trunk
Revision
181932
Author
achristen...@apple.com
Date
2015-03-24 22:19:42 -0700 (Tue, 24 Mar 2015)

Log Message

[Content Extensions] Add multi-DFA compiling and interpreting.
https://bugs.webkit.org/show_bug.cgi?id=143010

Reviewed by Benjamin Poulain.

Source/WebCore:

* contentextensions/ContentExtensionCompiler.cpp:
(WebCore::ContentExtensions::compileRuleList):
Compile multiple NFAs to DFAs.
* contentextensions/ContentExtensionsBackend.cpp:
(WebCore::ContentExtensions::ContentExtensionsBackend::actionsForResourceLoad):
Fixed a bug when there are no non-universal actions.
We still need to report that no ignore-previous-rules was hit to apply the
universal actions which are now accessed through DFABytecodeInterpreter::actionsFromDFARoot
and skipped in DFABytecodeInterpreter::interpret.
* contentextensions/DFABytecodeCompiler.cpp:
(WebCore::ContentExtensions::DFABytecodeCompiler::compile):
Add a header for each DFA.
* contentextensions/DFABytecodeInterpreter.cpp:
(WebCore::ContentExtensions::DFABytecodeInterpreter::actionsFromDFARoot):
(WebCore::ContentExtensions::DFABytecodeInterpreter::interpret):
Interpret as many DFAs as there are in the bytecode.

Tools:

* TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp:
(TestWebKitAPI::testRequest):
(TestWebKitAPI::TEST_F):
Add some tests for ignore-previous-rules and large rulesets.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (181931 => 181932)


--- trunk/Source/WebCore/ChangeLog	2015-03-25 05:12:49 UTC (rev 181931)
+++ trunk/Source/WebCore/ChangeLog	2015-03-25 05:19:42 UTC (rev 181932)
@@ -1,3 +1,27 @@
+2015-03-24  Alex Christensen  <achristen...@webkit.org>
+
+        [Content Extensions] Add multi-DFA compiling and interpreting.
+        https://bugs.webkit.org/show_bug.cgi?id=143010
+
+        Reviewed by Benjamin Poulain.
+
+        * contentextensions/ContentExtensionCompiler.cpp:
+        (WebCore::ContentExtensions::compileRuleList):
+        Compile multiple NFAs to DFAs.
+        * contentextensions/ContentExtensionsBackend.cpp:
+        (WebCore::ContentExtensions::ContentExtensionsBackend::actionsForResourceLoad):
+        Fixed a bug when there are no non-universal actions.
+        We still need to report that no ignore-previous-rules was hit to apply the
+        universal actions which are now accessed through DFABytecodeInterpreter::actionsFromDFARoot
+        and skipped in DFABytecodeInterpreter::interpret.
+        * contentextensions/DFABytecodeCompiler.cpp:
+        (WebCore::ContentExtensions::DFABytecodeCompiler::compile):
+        Add a header for each DFA.
+        * contentextensions/DFABytecodeInterpreter.cpp:
+        (WebCore::ContentExtensions::DFABytecodeInterpreter::actionsFromDFARoot):
+        (WebCore::ContentExtensions::DFABytecodeInterpreter::interpret):
+        Interpret as many DFAs as there are in the bytecode.
+
 2015-03-24  Dan Bernstein  <m...@apple.com>
 
         Tried to fix the EWS build.

Modified: trunk/Source/WebCore/contentextensions/ContentExtensionCompiler.cpp (181931 => 181932)


--- trunk/Source/WebCore/contentextensions/ContentExtensionCompiler.cpp	2015-03-25 05:12:49 UTC (rev 181931)
+++ trunk/Source/WebCore/contentextensions/ContentExtensionCompiler.cpp	2015-03-25 05:19:42 UTC (rev 181932)
@@ -111,16 +111,23 @@
     Vector<unsigned> actionLocations = serializeActions(parsedRuleList, actions);
     Vector<uint64_t> universalActionLocations;
 
-    NFA nfa;
-    URLFilterParser urlFilterParser(nfa);
+    Vector<NFA> nfas;
+    nfas.append(NFA());
     bool nonUniversalActionSeen = false;
     for (unsigned ruleIndex = 0; ruleIndex < parsedRuleList.size(); ++ruleIndex) {
+
+        // FIXME: Tune this better and adjust ContentExtensionTest.MultiDFA accordingly.
+        if (nfas[nfas.size() - 1].graphSize() > 500)
+            nfas.append(NFA());
+
+        NFA& lastNFA = nfas[nfas.size() - 1];
+        URLFilterParser urlFilterParser(lastNFA);
         const ContentExtensionRule& contentExtensionRule = parsedRuleList[ruleIndex];
         const Trigger& trigger = contentExtensionRule.trigger();
         ASSERT(trigger.urlFilter.length());
 
         // High bits are used for flags. This should match how they are used in DFABytecodeCompiler::compileNode.
-        uint64_t actionLocationAndFlags =(static_cast<uint64_t>(trigger.flags) << 32) | static_cast<uint64_t>(actionLocations[ruleIndex]);
+        uint64_t actionLocationAndFlags = (static_cast<uint64_t>(trigger.flags) << 32) | static_cast<uint64_t>(actionLocations[ruleIndex]);
         URLFilterParser::ParseStatus status = urlFilterParser.addPattern(trigger.urlFilter, trigger.urlFilterIsCaseSensitive, actionLocationAndFlags);
 
         if (status == URLFilterParser::MatchesEverything) {
@@ -149,9 +156,17 @@
     double dfaBuildTimeStart = monotonicallyIncreasingTime();
 #endif
 
-    DFA dfa = NFAToDFA::convert(nfa);
-    for (uint64_t actionLocation : universalActionLocations)
-        dfa.nodeAt(dfa.root()).actions.append(actionLocation);
+    Vector<DFABytecode> bytecode;
+    for (size_t i = 0; i < nfas.size(); ++i) {
+        DFA dfa = NFAToDFA::convert(nfas[i]);
+        if (!i) {
+            // Put all the universal actions on the first DFA.
+            for (uint64_t actionLocation : universalActionLocations)
+                dfa.nodeAt(dfa.root()).actions.append(actionLocation);
+        }
+        DFABytecodeCompiler compiler(dfa, bytecode);
+        compiler.compile();
+    }
 
 #if CONTENT_EXTENSIONS_PERFORMANCE_REPORTING
     double dfaBuildTimeEnd = monotonicallyIncreasingTime();
@@ -164,10 +179,6 @@
     dfa.debugPrintDot();
 #endif
 
-    Vector<DFABytecode> bytecode;
-    DFABytecodeCompiler compiler(dfa, bytecode);
-    compiler.compile();
-
     return { WTF::move(bytecode), WTF::move(actions) };
 }
 

Modified: trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.cpp (181931 => 181932)


--- trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.cpp	2015-03-25 05:12:49 UTC (rev 181931)
+++ trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.cpp	2015-03-25 05:19:42 UTC (rev 181932)
@@ -80,6 +80,7 @@
         const SerializedActionByte* actions = compiledExtension.actions();
         const unsigned actionsLength = compiledExtension.actionsLength();
         
+        bool sawIgnorePreviousRules = false;
         if (!triggeredActions.isEmpty()) {
             Vector<unsigned> actionLocations;
             actionLocations.reserveInitialCapacity(triggeredActions.size());
@@ -87,8 +88,6 @@
                 actionLocations.append(static_cast<unsigned>(actionLocation));
             std::sort(actionLocations.begin(), actionLocations.end());
 
-            bool sawIgnorePreviousRules = false;
-
             // Add actions in reverse order to properly deal with IgnorePreviousRules.
             for (unsigned i = actionLocations.size(); i; i--) {
                 Action action = "" actionsLength, actionLocations[i - 1]);
@@ -98,10 +97,9 @@
                 }
                 finalActions.append(action);
             }
-
-            if (!sawIgnorePreviousRules)
-                finalActions.append(Action(ActionType::CSSDisplayNoneStyleSheet, contentExtension->identifier()));
         }
+        if (!sawIgnorePreviousRules)
+            finalActions.append(Action(ActionType::CSSDisplayNoneStyleSheet, contentExtension->identifier()));
     }
     return finalActions;
 }

Modified: trunk/Source/WebCore/contentextensions/DFABytecodeCompiler.cpp (181931 => 181932)


--- trunk/Source/WebCore/contentextensions/DFABytecodeCompiler.cpp	2015-03-25 05:12:49 UTC (rev 181931)
+++ trunk/Source/WebCore/contentextensions/DFABytecodeCompiler.cpp	2015-03-25 05:19:42 UTC (rev 181932)
@@ -167,7 +167,9 @@
 
 void DFABytecodeCompiler::compile()
 {
-    ASSERT(!m_bytecode.size());
+    // DFA header.
+    unsigned startLocation = m_bytecode.size();
+    append<unsigned>(m_bytecode, 0);
     m_nodeStartOffsets.resize(m_dfa.size());
     
     // Make sure the root is always at the beginning of the bytecode.
@@ -180,6 +182,9 @@
     // Link.
     for (const auto& linkRecord : m_linkRecords)
         set32Bits(m_bytecode, linkRecord.first, m_nodeStartOffsets[linkRecord.second]);
+    
+    // Set size header.
+    set32Bits(m_bytecode, startLocation, m_bytecode.size() - startLocation);
 }
     
 } // namespace ContentExtensions

Modified: trunk/Source/WebCore/contentextensions/DFABytecodeInterpreter.cpp (181931 => 181932)


--- trunk/Source/WebCore/contentextensions/DFABytecodeInterpreter.cpp	2015-03-25 05:12:49 UTC (rev 181931)
+++ trunk/Source/WebCore/contentextensions/DFABytecodeInterpreter.cpp	2015-03-25 05:19:42 UTC (rev 181932)
@@ -43,13 +43,15 @@
     
 DFABytecodeInterpreter::Actions DFABytecodeInterpreter::actionsFromDFARoot()
 {
-    unsigned programCounter = 0;
-    DFABytecodeInterpreter::Actions globalActionLocations;
+    DFABytecodeInterpreter::Actions universalActionLocations;
+
+    // Skip first DFA header. All universal actions are in the first DFA root.
+    unsigned programCounter = sizeof(unsigned);
     while (static_cast<DFABytecodeInstruction>(m_bytecode[programCounter]) == DFABytecodeInstruction::AppendAction) {
-        globalActionLocations.add(static_cast<uint64_t>(getBits<unsigned>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode))));
+        universalActionLocations.add(static_cast<uint64_t>(getBits<unsigned>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode))));
         programCounter += instructionSizeWithArguments(DFABytecodeInstruction::AppendAction);
     }
-    return globalActionLocations;
+    return universalActionLocations;
 }
     
 DFABytecodeInterpreter::Actions DFABytecodeInterpreter::interpret(const CString& urlCString, uint16_t flags)
@@ -57,78 +59,92 @@
     const char* url = ""
     ASSERT(url);
     
-    unsigned programCounter = 0;
-    unsigned urlIndex = 0;
-    bool urlIndexIsAfterEndOfString = false;
     Actions actions;
     
-    while (static_cast<DFABytecodeInstruction>(m_bytecode[programCounter]) == DFABytecodeInstruction::AppendAction)
-        programCounter += instructionSizeWithArguments(DFABytecodeInstruction::AppendAction);
+    unsigned programCounter = 0;
+    while (programCounter < m_bytecodeLength) {
 
-    // This should always terminate if interpreting correctly compiled bytecode.
-    while (true) {
-        ASSERT(programCounter <= m_bytecodeLength);
-        switch (static_cast<DFABytecodeInstruction>(m_bytecode[programCounter])) {
+        // DFA header.
+        unsigned dfaStart = programCounter;
+        unsigned dfaBytecodeLength = getBits<unsigned>(m_bytecode, m_bytecodeLength, programCounter);
+        programCounter += sizeof(unsigned);
 
-        case DFABytecodeInstruction::Terminate:
-            return actions;
+        // Skip the universal actions.
+        // FIXME: Replace AppendAction with AppendActions to make this just one jump and make sure there aren't universal actions with flags.
+        while (static_cast<DFABytecodeInstruction>(m_bytecode[programCounter]) == DFABytecodeInstruction::AppendAction)
+            programCounter += instructionSizeWithArguments(DFABytecodeInstruction::AppendAction);
+        
+        // Interpret the bytecode from this DFA.
+        // This should always terminate if interpreting correctly compiled bytecode.
+        unsigned urlIndex = 0;
+        bool urlIndexIsAfterEndOfString = false;
+        while (true) {
+            ASSERT(programCounter <= m_bytecodeLength);
+            switch (static_cast<DFABytecodeInstruction>(m_bytecode[programCounter])) {
 
-        case DFABytecodeInstruction::CheckValue:
-            if (urlIndexIsAfterEndOfString)
-                return actions;
+            case DFABytecodeInstruction::Terminate:
+                goto nextDFA;
+                    
+            case DFABytecodeInstruction::CheckValue:
+                if (urlIndexIsAfterEndOfString)
+                    goto nextDFA;
 
-            // Check to see if the next character in the url is the value stored with the bytecode.
-            if (url[urlIndex] == getBits<uint8_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode))) {
-                programCounter = getBits<unsigned>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode) + sizeof(uint8_t));
-                if (!url[urlIndex])
-                    urlIndexIsAfterEndOfString = true;
-                urlIndex++; // This represents an edge in the DFA.
-            } else
-                programCounter += instructionSizeWithArguments(DFABytecodeInstruction::CheckValue);
-            break;
+                // Check to see if the next character in the url is the value stored with the bytecode.
+                if (url[urlIndex] == getBits<uint8_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode))) {
+                    programCounter = getBits<unsigned>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode) + sizeof(uint8_t));
+                    if (!url[urlIndex])
+                        urlIndexIsAfterEndOfString = true;
+                    urlIndex++; // This represents an edge in the DFA.
+                } else
+                    programCounter += instructionSizeWithArguments(DFABytecodeInstruction::CheckValue);
+                break;
+                    
+            case DFABytecodeInstruction::CheckValueRange: {
+                if (urlIndexIsAfterEndOfString)
+                    goto nextDFA;
+                
+                char character = url[urlIndex];
+                if (character >= getBits<uint8_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode))
+                    && character <= getBits<uint8_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode) + sizeof(uint8_t))) {
+                    programCounter = getBits<unsigned>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode) + sizeof(uint8_t) + sizeof(uint8_t));
+                    if (!character)
+                        urlIndexIsAfterEndOfString = true;
+                    urlIndex++; // This represents an edge in the DFA.
+                } else
+                    programCounter += instructionSizeWithArguments(DFABytecodeInstruction::CheckValueRange);
+                break;
+            }
 
-        case DFABytecodeInstruction::CheckValueRange: {
-            if (urlIndexIsAfterEndOfString)
-                return actions;
-
-            char character = url[urlIndex];
-            if (character >= getBits<uint8_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode))
-                && character <= getBits<uint8_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode) + sizeof(uint8_t))) {
-                programCounter = getBits<unsigned>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode) + sizeof(uint8_t) + sizeof(uint8_t));
-                if (!character)
-                    urlIndexIsAfterEndOfString = true;
+            case DFABytecodeInstruction::Jump:
+                if (!url[urlIndex] || urlIndexIsAfterEndOfString)
+                    goto nextDFA;
+                
+                programCounter = getBits<unsigned>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode));
                 urlIndex++; // This represents an edge in the DFA.
-            } else
-                programCounter += instructionSizeWithArguments(DFABytecodeInstruction::CheckValueRange);
-            break;
+                break;
+                    
+            case DFABytecodeInstruction::AppendAction:
+                actions.add(static_cast<uint64_t>(getBits<unsigned>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode))));
+                programCounter += instructionSizeWithArguments(DFABytecodeInstruction::AppendAction);
+                break;
+                    
+            case DFABytecodeInstruction::TestFlagsAndAppendAction:
+                if (flags & getBits<uint16_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode)))
+                    actions.add(static_cast<uint64_t>(getBits<unsigned>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode) + sizeof(uint16_t))));
+                programCounter += instructionSizeWithArguments(DFABytecodeInstruction::TestFlagsAndAppendAction);
+                break;
+                    
+            default:
+                RELEASE_ASSERT_NOT_REACHED(); // Invalid bytecode.
+            }
+            // We should always terminate before or at a null character at the end of a String.
+            ASSERT(urlIndex <= urlCString.length() || (urlIndexIsAfterEndOfString && urlIndex <= urlCString.length() + 1));
         }
-
-        case DFABytecodeInstruction::Jump:
-            if (!url[urlIndex] || urlIndexIsAfterEndOfString)
-                return actions;
-
-            programCounter = getBits<unsigned>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode));
-            urlIndex++; // This represents an edge in the DFA.
-            break;
-
-        case DFABytecodeInstruction::AppendAction:
-            actions.add(static_cast<uint64_t>(getBits<unsigned>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode))));
-            programCounter += instructionSizeWithArguments(DFABytecodeInstruction::AppendAction);
-            break;
-
-        case DFABytecodeInstruction::TestFlagsAndAppendAction:
-            if (flags & getBits<uint16_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode)))
-                actions.add(static_cast<uint64_t>(getBits<unsigned>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode) + sizeof(uint16_t))));
-            programCounter += instructionSizeWithArguments(DFABytecodeInstruction::TestFlagsAndAppendAction);
-            break;
-
-        default:
-            RELEASE_ASSERT_NOT_REACHED(); // Invalid bytecode.
-        }
-        // We should always terminate before or at a null character at the end of a String.
-        ASSERT(urlIndex <= urlCString.length() || (urlIndexIsAfterEndOfString && urlIndex <= urlCString.length() + 1));
+        nextDFA:
+        ASSERT(dfaBytecodeLength);
+        programCounter = dfaStart + dfaBytecodeLength;
     }
-    RELEASE_ASSERT_NOT_REACHED();
+    return actions;
 }
 
 } // namespace ContentExtensions

Modified: trunk/Tools/ChangeLog (181931 => 181932)


--- trunk/Tools/ChangeLog	2015-03-25 05:12:49 UTC (rev 181931)
+++ trunk/Tools/ChangeLog	2015-03-25 05:19:42 UTC (rev 181932)
@@ -1,3 +1,15 @@
+2015-03-24  Alex Christensen  <achristen...@webkit.org>
+
+        [Content Extensions] Add multi-DFA compiling and interpreting.
+        https://bugs.webkit.org/show_bug.cgi?id=143010
+
+        Reviewed by Benjamin Poulain.
+
+        * TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp:
+        (TestWebKitAPI::testRequest):
+        (TestWebKitAPI::TEST_F):
+        Add some tests for ignore-previous-rules and large rulesets.
+
 2015-03-24  Benjamin Poulain  <bpoul...@apple.com>
 
         Make URL filter patterns matching consistent and add a simple canonicalization step

Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp (181931 => 181932)


--- trunk/Tools/TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp	2015-03-25 05:12:49 UTC (rev 181931)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp	2015-03-25 05:19:42 UTC (rev 181932)
@@ -36,6 +36,7 @@
 #include <wtf/MainThread.h>
 #include <wtf/RunLoop.h>
 #include <wtf/text/CString.h>
+#include <wtf/text/StringBuilder.h>
 
 namespace WebCore {
 namespace ContentExtensions {
@@ -98,16 +99,22 @@
     ContentExtensions::CompiledContentExtensionData m_data;
 };
 
-void static testRequest(ContentExtensions::ContentExtensionsBackend contentExtensionsBackend, const ResourceLoadInfo& resourceLoadInfo, Vector<ContentExtensions::ActionType> expectedActions)
+void static testRequest(ContentExtensions::ContentExtensionsBackend contentExtensionsBackend, const ResourceLoadInfo& resourceLoadInfo, Vector<ContentExtensions::ActionType> expectedActions, bool ignorePreviousRules = false)
 {
     auto actions = contentExtensionsBackend.actionsForResourceLoad(resourceLoadInfo);
-    // The last action is applying the compiled stylesheet.
-    EXPECT_EQ(expectedActions.size(), actions.size() ? actions.size() - 1 : 0);
-    if (expectedActions.size() != (actions.size() ? actions.size() - 1 : 0))
+
+    unsigned expectedSize = actions.size();
+    if (actions.size() && !ignorePreviousRules)
+        expectedSize--; // The last action is applying the compiled stylesheet.
+    
+    EXPECT_EQ(expectedActions.size(), expectedSize);
+    if (expectedActions.size() != expectedSize)
         return;
 
     for (unsigned i = 0; i < expectedActions.size(); ++i)
         EXPECT_EQ(expectedActions[i], actions[i].type());
+    if (!ignorePreviousRules)
+        EXPECT_EQ(actions[actions.size() - 1].type(), ContentExtensions::ActionType::CSSDisplayNoneStyleSheet);
 }
 
 ResourceLoadInfo mainDocumentRequest(const char* url, ResourceType resourceType = ResourceType::Document)
@@ -510,6 +517,47 @@
     testRequest(backend, mainDocumentRequest("http://block_only_images.org", ResourceType::Document), { });
 }
 
+TEST_F(ContentExtensionTest, MultiDFA)
+{
+    // Make an NFA with about 2000 nodes.
+    StringBuilder ruleList;
+    ruleList.append('[');
+    for (char c1 = 'A'; c1 <= 'Z'; ++c1) {
+        for (char c2 = 'A'; c2 <= 'Z'; ++c2) {
+            for (char c3 = 'A'; c3 <= 'C'; ++c3) {
+                if (c1 != 'A' || c2 != 'A' || c3 != 'A')
+                    ruleList.append(',');
+                ruleList.append("{\"action\":{\"type\":\"");
+                
+                // Put an ignore-previous-rules near the middle.
+                if (c1 == 'L' && c2 == 'L' && c3 == 'A')
+                    ruleList.append("ignore-previous-rules");
+                else
+                    ruleList.append("block");
+                
+                ruleList.append("\"},\"trigger\":{\"url-filter\":\".*");
+                ruleList.append(c1);
+                ruleList.append(c2);
+                ruleList.append(c3);
+                ruleList.append("\", \"url-filter-is-case-sensitive\":true}}");
+            }
+        }
+    }
+    ruleList.append(']');
+    
+    auto extensionData = ContentExtensions::compileRuleList(ruleList.toString());
+    auto extension = InMemoryCompiledContentExtension::create(WTF::move(extensionData));
+        
+    ContentExtensions::ContentExtensionsBackend backend;
+    backend.addContentExtension("ResourceTypeFilter", extension);
+
+    testRequest(backend, mainDocumentRequest("http://webkit.org/AAA"), { ContentExtensions::ActionType::BlockLoad });
+    testRequest(backend, mainDocumentRequest("http://webkit.org/ZZC"), { ContentExtensions::ActionType::BlockLoad });
+    testRequest(backend, mainDocumentRequest("http://webkit.org/LLA/AAA"), { }, true);
+    testRequest(backend, mainDocumentRequest("http://webkit.org/LLA/MMC"), { ContentExtensions::ActionType::BlockLoad }, true);
+    testRequest(backend, mainDocumentRequest("http://webkit.org/"), { });
+}
+
 static void testPatternStatus(String pattern, ContentExtensions::URLFilterParser::ParseStatus status)
 {
     ContentExtensions::NFA nfa;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to