Title: [286383] trunk
Revision
286383
Author
[email protected]
Date
2021-12-01 13:31:04 -0800 (Wed, 01 Dec 2021)

Log Message

Add csp-report resource type to WKContentRuleList
https://bugs.webkit.org/show_bug.cgi?id=233675
<rdar://71869893>

Reviewed by Tim Hatcher.

Source/WebCore:

This feature is trivial to implement and test except for one small thing: we use a uint16_t to represent the
resource type and context and first party flags, and we already have 16 of them.  So we needed to get another
bit from somewhere.  What I did was make the flags have a variable length from 1-3 bytes instead of just 2 bytes.
I used the unused upper bits in the instruction to indicate the length of the flags, and if the upper bits were 0,
then I assume it was 2 bytes, which is binary compatible with existing compiled WKContentRuleLists, so no need
to increment the version number and force a recompile.  It worked so well that I did the same thing with the actions,
which were 4 bytes but are now 1-4 bytes.  This reduced the compiled binary size of one of the tests from 313 bytes
to 288 bytes, a reduction of about 8% of the binary size of the compiled WKContentRuleLists.  Larger lists will see
slightly less binary size reduction, but still an improvement.

* contentextensions/ContentExtension.cpp:
(WebCore::ContentExtensions::ContentExtension::ContentExtension):
(WebCore::ContentExtensions::ContentExtension::populateConditionCacheIfNeeded):
* contentextensions/ContentExtensionsBackend.cpp:
(WebCore::ContentExtensions::ContentExtensionsBackend::actionsForResourceLoad const):
* contentextensions/DFABytecode.h:
(WebCore::ContentExtensions::smallestPossibleJumpSize):
(): Deleted.
(WebCore::ContentExtensions::instructionSizeWithArguments): Deleted.
* contentextensions/DFABytecodeCompiler.cpp:
(WebCore::ContentExtensions::append):
(WebCore::ContentExtensions::append24BitInteger):
(WebCore::ContentExtensions::appendZeroes):
(WebCore::ContentExtensions::setBits):
(WebCore::ContentExtensions::bytecodeFlagsSize):
(WebCore::ContentExtensions::bytecodeActionSize):
(WebCore::ContentExtensions::appendVariableLengthInteger):
(WebCore::ContentExtensions::DFABytecodeCompiler::emitAppendAction):
(WebCore::ContentExtensions::DFABytecodeCompiler::emitJump):
(WebCore::ContentExtensions::DFABytecodeCompiler::emitCheckValue):
(WebCore::ContentExtensions::DFABytecodeCompiler::emitCheckValueRange):
(WebCore::ContentExtensions::DFABytecodeCompiler::transitions):
(WebCore::ContentExtensions::DFABytecodeCompiler::compileJumpTable):
(WebCore::ContentExtensions::DFABytecodeCompiler::nodeTransitionsMaxBytecodeSize):
(WebCore::ContentExtensions::DFABytecodeCompiler::compile):
* contentextensions/DFABytecodeInterpreter.cpp:
(WebCore::ContentExtensions::getBits):
(WebCore::ContentExtensions::get24Bits):
(WebCore::ContentExtensions::getInstruction):
(WebCore::ContentExtensions::jumpSizeInBytes):
(WebCore::ContentExtensions::consumeInteger):
(WebCore::ContentExtensions::consume24BitInteger):
(WebCore::ContentExtensions::hasFlags):
(WebCore::ContentExtensions::hasAction):
(WebCore::ContentExtensions::consumeResourceFlagsAndInstruction):
(WebCore::ContentExtensions::consumeAction):
(WebCore::ContentExtensions::getJumpSize):
(WebCore::ContentExtensions::getJumpDistance):
(WebCore::ContentExtensions::matchesCondition):
(WebCore::ContentExtensions::DFABytecodeInterpreter::interpretAppendAction):
(WebCore::ContentExtensions::DFABytecodeInterpreter::interpretTestFlagsAndAppendAction):
(WebCore::ContentExtensions::DFABytecodeInterpreter::interpetJumpTable):
(WebCore::ContentExtensions::DFABytecodeInterpreter::actionsMatchingEverything):
(WebCore::ContentExtensions::DFABytecodeInterpreter::interpretWithConditions):
(WebCore::ContentExtensions::DFABytecodeInterpreter::interpret):
* contentextensions/DFABytecodeInterpreter.h:
(WebCore::ContentExtensions::DFABytecodeInterpreter::DFABytecodeInterpreter):
* loader/PingLoader.cpp:
(WebCore::PingLoader::sendViolationReport):
* loader/ResourceLoadInfo.cpp:
(WebCore::ContentExtensions::readResourceType):
* loader/ResourceLoadInfo.h:

Tools:

* TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp:
(TestWebKitAPI::compareContents):
(TestWebKitAPI::TEST_F):
* TestWebKitAPI/Tests/WebKitCocoa/ContentRuleListNotification.mm:
(TEST):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (286382 => 286383)


--- trunk/Source/WebCore/ChangeLog	2021-12-01 21:25:07 UTC (rev 286382)
+++ trunk/Source/WebCore/ChangeLog	2021-12-01 21:31:04 UTC (rev 286383)
@@ -1,3 +1,74 @@
+2021-12-01  Alex Christensen  <[email protected]>
+
+        Add csp-report resource type to WKContentRuleList
+        https://bugs.webkit.org/show_bug.cgi?id=233675
+        <rdar://71869893>
+
+        Reviewed by Tim Hatcher.
+
+        This feature is trivial to implement and test except for one small thing: we use a uint16_t to represent the
+        resource type and context and first party flags, and we already have 16 of them.  So we needed to get another
+        bit from somewhere.  What I did was make the flags have a variable length from 1-3 bytes instead of just 2 bytes.
+        I used the unused upper bits in the instruction to indicate the length of the flags, and if the upper bits were 0,
+        then I assume it was 2 bytes, which is binary compatible with existing compiled WKContentRuleLists, so no need
+        to increment the version number and force a recompile.  It worked so well that I did the same thing with the actions,
+        which were 4 bytes but are now 1-4 bytes.  This reduced the compiled binary size of one of the tests from 313 bytes
+        to 288 bytes, a reduction of about 8% of the binary size of the compiled WKContentRuleLists.  Larger lists will see
+        slightly less binary size reduction, but still an improvement.
+
+        * contentextensions/ContentExtension.cpp:
+        (WebCore::ContentExtensions::ContentExtension::ContentExtension):
+        (WebCore::ContentExtensions::ContentExtension::populateConditionCacheIfNeeded):
+        * contentextensions/ContentExtensionsBackend.cpp:
+        (WebCore::ContentExtensions::ContentExtensionsBackend::actionsForResourceLoad const):
+        * contentextensions/DFABytecode.h:
+        (WebCore::ContentExtensions::smallestPossibleJumpSize):
+        (): Deleted.
+        (WebCore::ContentExtensions::instructionSizeWithArguments): Deleted.
+        * contentextensions/DFABytecodeCompiler.cpp:
+        (WebCore::ContentExtensions::append):
+        (WebCore::ContentExtensions::append24BitInteger):
+        (WebCore::ContentExtensions::appendZeroes):
+        (WebCore::ContentExtensions::setBits):
+        (WebCore::ContentExtensions::bytecodeFlagsSize):
+        (WebCore::ContentExtensions::bytecodeActionSize):
+        (WebCore::ContentExtensions::appendVariableLengthInteger):
+        (WebCore::ContentExtensions::DFABytecodeCompiler::emitAppendAction):
+        (WebCore::ContentExtensions::DFABytecodeCompiler::emitJump):
+        (WebCore::ContentExtensions::DFABytecodeCompiler::emitCheckValue):
+        (WebCore::ContentExtensions::DFABytecodeCompiler::emitCheckValueRange):
+        (WebCore::ContentExtensions::DFABytecodeCompiler::transitions):
+        (WebCore::ContentExtensions::DFABytecodeCompiler::compileJumpTable):
+        (WebCore::ContentExtensions::DFABytecodeCompiler::nodeTransitionsMaxBytecodeSize):
+        (WebCore::ContentExtensions::DFABytecodeCompiler::compile):
+        * contentextensions/DFABytecodeInterpreter.cpp:
+        (WebCore::ContentExtensions::getBits):
+        (WebCore::ContentExtensions::get24Bits):
+        (WebCore::ContentExtensions::getInstruction):
+        (WebCore::ContentExtensions::jumpSizeInBytes):
+        (WebCore::ContentExtensions::consumeInteger):
+        (WebCore::ContentExtensions::consume24BitInteger):
+        (WebCore::ContentExtensions::hasFlags):
+        (WebCore::ContentExtensions::hasAction):
+        (WebCore::ContentExtensions::consumeResourceFlagsAndInstruction):
+        (WebCore::ContentExtensions::consumeAction):
+        (WebCore::ContentExtensions::getJumpSize):
+        (WebCore::ContentExtensions::getJumpDistance):
+        (WebCore::ContentExtensions::matchesCondition):
+        (WebCore::ContentExtensions::DFABytecodeInterpreter::interpretAppendAction):
+        (WebCore::ContentExtensions::DFABytecodeInterpreter::interpretTestFlagsAndAppendAction):
+        (WebCore::ContentExtensions::DFABytecodeInterpreter::interpetJumpTable):
+        (WebCore::ContentExtensions::DFABytecodeInterpreter::actionsMatchingEverything):
+        (WebCore::ContentExtensions::DFABytecodeInterpreter::interpretWithConditions):
+        (WebCore::ContentExtensions::DFABytecodeInterpreter::interpret):
+        * contentextensions/DFABytecodeInterpreter.h:
+        (WebCore::ContentExtensions::DFABytecodeInterpreter::DFABytecodeInterpreter):
+        * loader/PingLoader.cpp:
+        (WebCore::PingLoader::sendViolationReport):
+        * loader/ResourceLoadInfo.cpp:
+        (WebCore::ContentExtensions::readResourceType):
+        * loader/ResourceLoadInfo.h:
+
 2021-12-01  Rob Buis  <[email protected]>
 
         Remove virtual from RenderWidget::paintContents

Modified: trunk/Source/WebCore/contentextensions/ContentExtension.cpp (286382 => 286383)


--- trunk/Source/WebCore/contentextensions/ContentExtension.cpp	2021-12-01 21:25:07 UTC (rev 286382)
+++ trunk/Source/WebCore/contentextensions/ContentExtension.cpp	2021-12-01 21:31:04 UTC (rev 286383)
@@ -46,8 +46,8 @@
     , m_compiledExtension(WTFMove(compiledExtension))
     , m_extensionBaseURL(WTFMove(extensionBaseURL))
 {
-    DFABytecodeInterpreter withoutConditions(m_compiledExtension->filtersWithoutConditionsBytecode(), m_compiledExtension->filtersWithoutConditionsBytecodeLength());
-    DFABytecodeInterpreter withConditions(m_compiledExtension->filtersWithConditionsBytecode(), m_compiledExtension->filtersWithConditionsBytecodeLength());
+    DFABytecodeInterpreter withoutConditions({ m_compiledExtension->filtersWithoutConditionsBytecode(), m_compiledExtension->filtersWithoutConditionsBytecodeLength() });
+    DFABytecodeInterpreter withConditions({ m_compiledExtension->filtersWithConditionsBytecode(), m_compiledExtension->filtersWithConditionsBytecodeLength() });
     for (uint64_t action : withoutConditions.actionsMatchingEverything()) {
         ASSERT(static_cast<uint32_t>(action) == action);
         m_universalActionsWithoutConditions.append(static_cast<uint32_t>(action));
@@ -123,8 +123,8 @@
 void ContentExtension::populateConditionCacheIfNeeded(const URL& topURL)
 {
     if (m_cachedTopURL != topURL) {
-        DFABytecodeInterpreter interpreter(m_compiledExtension->topURLFiltersBytecode(), m_compiledExtension->topURLFiltersBytecodeLength());
-        constexpr uint16_t allLoadTypesAndResourceTypes = LoadTypeMask | ResourceTypeMask | LoadContextMask;
+        DFABytecodeInterpreter interpreter({ m_compiledExtension->topURLFiltersBytecode(), m_compiledExtension->topURLFiltersBytecodeLength() });
+        constexpr ResourceFlags allLoadTypesAndResourceTypes = LoadTypeMask | ResourceTypeMask | LoadContextMask;
         String string = m_compiledExtension->conditionsApplyOnlyToDomain() ? topURL.host().toString() : topURL.string();
         auto topURLActions = interpreter.interpret(string.utf8(), allLoadTypesAndResourceTypes);
         

Modified: trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.cpp (286382 => 286383)


--- trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.cpp	2021-12-01 21:25:07 UTC (rev 286382)
+++ trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.cpp	2021-12-01 21:31:04 UTC (rev 286383)
@@ -121,11 +121,11 @@
 
         const CompiledContentExtension& compiledExtension = contentExtension->compiledExtension();
         
-        DFABytecodeInterpreter withoutConditionsInterpreter(compiledExtension.filtersWithoutConditionsBytecode(), compiledExtension.filtersWithoutConditionsBytecodeLength());
+        DFABytecodeInterpreter withoutConditionsInterpreter({ compiledExtension.filtersWithoutConditionsBytecode(), compiledExtension.filtersWithoutConditionsBytecodeLength() });
         DFABytecodeInterpreter::Actions withoutConditionsActions = withoutConditionsInterpreter.interpret(urlCString, flags);
         
         URL topURL = resourceLoadInfo.mainDocumentURL;
-        DFABytecodeInterpreter withConditionsInterpreter(compiledExtension.filtersWithConditionsBytecode(), compiledExtension.filtersWithConditionsBytecodeLength());
+        DFABytecodeInterpreter withConditionsInterpreter({ compiledExtension.filtersWithConditionsBytecode(), compiledExtension.filtersWithConditionsBytecodeLength() });
         DFABytecodeInterpreter::Actions withConditionsActions = withConditionsInterpreter.interpretWithConditions(urlCString, flags, contentExtension->topURLActions(topURL));
         
         const SerializedActionByte* actions = compiledExtension.actions();

Modified: trunk/Source/WebCore/contentextensions/DFABytecode.h (286382 => 286383)


--- trunk/Source/WebCore/contentextensions/DFABytecode.h	2021-12-01 21:25:07 UTC (rev 286382)
+++ trunk/Source/WebCore/contentextensions/DFABytecode.h	2021-12-01 21:31:04 UTC (rev 286383)
@@ -27,11 +27,9 @@
 
 #if ENABLE(CONTENT_EXTENSIONS)
 
-namespace WebCore {
-    
-namespace ContentExtensions {
+namespace WebCore::ContentExtensions {
 
-typedef uint8_t DFABytecode;
+using DFABytecode = uint8_t;
 
 // Increment ContentExtensionStore::CurrentContentExtensionFileVersion
 // when making any non-backwards-compatible changes to the bytecode.
@@ -60,13 +58,13 @@
     CheckValueRangeCaseSensitive = 0x5,
 
     // AppendAction has one argument:
-    // The action to append (4 bytes).
+    // The action to append (1-4 bytes).
     AppendAction = 0x6,
     AppendActionWithIfCondition = 0x7,
     
     // TestFlagsAndAppendAction has two arguments:
-    // The flags to check before appending (2 bytes).
-    // The action to append (4 bytes).
+    // The flags to check before appending (1-3 bytes).
+    // The action to append (1-4 bytes).
     TestFlagsAndAppendAction = 0x8,
     TestFlagsAndAppendActionWithIfCondition = 0x9,
 
@@ -79,57 +77,51 @@
 };
 
 // The last four bits contain the instruction type.
-const uint8_t DFABytecodeInstructionMask = 0x0F;
-const uint8_t DFABytecodeJumpSizeMask = 0xF0;
+static constexpr uint8_t DFABytecodeInstructionMask = 0x0F;
+static constexpr uint8_t DFABytecodeJumpSizeMask = 0xF0;
+static constexpr uint8_t DFABytecodeFlagsSizeMask = 0x30;
+static constexpr uint8_t DFABytecodeActionSizeMask = 0xC0;
 
 // DFA bytecode starts with a 4 byte header which contains the size of this DFA.
-typedef uint32_t DFAHeader;
+using DFAHeader = uint32_t;
 
+// DFABytecodeFlagsSize and DFABytecodeActionSize are stored in the top four bits of the DFABytecodeInstructions that have flags and actions.
+enum class DFABytecodeFlagsSize : uint8_t {
+    UInt8 = 0x10,
+    UInt16 = 0x00, // Needs to be zero to be binary compatible with bytecode compiled with fixed-size flags.
+    UInt24 = 0x20,
+};
+enum class DFABytecodeActionSize : uint8_t {
+    UInt8 = 0x40,
+    UInt16 = 0x80,
+    UInt24 = 0xC0,
+    UInt32 = 0x00, // Needs to be zero to be binary compatible with bytecode compiled with fixed-size actions.
+};
+
 // A DFABytecodeJumpSize is stored in the top four bits of the DFABytecodeInstructions that have a jump.
-enum DFABytecodeJumpSize {
+enum class DFABytecodeJumpSize : uint8_t {
     Int8 = 0x10,
     Int16 = 0x20,
     Int24 = 0x30,
     Int32 = 0x40,
 };
-const int32_t Int24Max = (1 << 23) - 1;
-const int32_t Int24Min = -(1 << 23);
+static constexpr int32_t UInt24Max = (1 << 24) - 1;
+static constexpr int32_t Int24Max = (1 << 23) - 1;
+static constexpr int32_t Int24Min = -(1 << 23);
+static constexpr size_t Int24Size = 3;
+static constexpr size_t UInt24Size = 3;
 
 static inline DFABytecodeJumpSize smallestPossibleJumpSize(int32_t longestPossibleJump)
 {
     if (longestPossibleJump <= std::numeric_limits<int8_t>::max() && longestPossibleJump >= std::numeric_limits<int8_t>::min())
-        return Int8;
+        return DFABytecodeJumpSize::Int8;
     if (longestPossibleJump <= std::numeric_limits<int16_t>::max() && longestPossibleJump >= std::numeric_limits<int16_t>::min())
-        return Int16;
+        return DFABytecodeJumpSize::Int16;
     if (longestPossibleJump <= Int24Max && longestPossibleJump >= Int24Min)
-        return Int24;
-    return Int32;
+        return DFABytecodeJumpSize::Int24;
+    return DFABytecodeJumpSize::Int32;
 }
-    
-static inline size_t instructionSizeWithArguments(DFABytecodeInstruction instruction)
-{
-    switch (instruction) {
-    case DFABytecodeInstruction::CheckValueCaseSensitive:
-    case DFABytecodeInstruction::CheckValueCaseInsensitive:
-    case DFABytecodeInstruction::JumpTableCaseInsensitive:
-    case DFABytecodeInstruction::JumpTableCaseSensitive:
-    case DFABytecodeInstruction::CheckValueRangeCaseSensitive:
-    case DFABytecodeInstruction::CheckValueRangeCaseInsensitive:
-    case DFABytecodeInstruction::Jump:
-        RELEASE_ASSERT_NOT_REACHED(); // Variable instruction size.
-    case DFABytecodeInstruction::AppendAction:
-    case DFABytecodeInstruction::AppendActionWithIfCondition:
-        return sizeof(DFABytecodeInstruction) + sizeof(uint32_t);
-    case DFABytecodeInstruction::TestFlagsAndAppendAction:
-    case DFABytecodeInstruction::TestFlagsAndAppendActionWithIfCondition:
-        return sizeof(DFABytecodeInstruction) + sizeof(uint16_t) + sizeof(uint32_t);
-    case DFABytecodeInstruction::Terminate:
-        return sizeof(DFABytecodeInstruction);
-    }
-    RELEASE_ASSERT_NOT_REACHED();
-}
-    
-} // namespace ContentExtensions    
-} // namespace WebCore
 
+} // namespace WebCore::ContentExtensions
+
 #endif // ENABLE(CONTENT_EXTENSIONS)

Modified: trunk/Source/WebCore/contentextensions/DFABytecodeCompiler.cpp (286382 => 286383)


--- trunk/Source/WebCore/contentextensions/DFABytecodeCompiler.cpp	2021-12-01 21:25:07 UTC (rev 286382)
+++ trunk/Source/WebCore/contentextensions/DFABytecodeCompiler.cpp	2021-12-01 21:31:04 UTC (rev 286383)
@@ -32,19 +32,23 @@
 #include "DFA.h"
 #include "DFANode.h"
 
-namespace WebCore {
-    
-namespace ContentExtensions {
+namespace WebCore::ContentExtensions {
 
 template <typename IntType>
-inline void append(Vector<DFABytecode>& bytecode, IntType value)
+void append(Vector<DFABytecode>& bytecode, IntType value)
 {
     bytecode.grow(bytecode.size() + sizeof(IntType));
     memcpy(&bytecode[bytecode.size() - sizeof(IntType)], &value, sizeof(IntType));
 }
 
-inline void appendZeroes(Vector<DFABytecode>& bytecode, DFABytecodeJumpSize jumpSize)
+static void append24BitUnsignedInteger(Vector<DFABytecode>& bytecode, uint32_t value)
 {
+    append<uint16_t>(bytecode, value);
+    append<uint8_t>(bytecode, value >> 16);
+}
+
+static void appendZeroes(Vector<DFABytecode>& bytecode, DFABytecodeJumpSize jumpSize)
+{
     switch (jumpSize) {
     case DFABytecodeJumpSize::Int8:
         append<int8_t>(bytecode, 0); // This value will be set when linking.
@@ -63,7 +67,7 @@
 }
 
 template <typename IntType>
-inline void setBits(Vector<DFABytecode>& bytecode, uint32_t index, IntType value)
+void setBits(Vector<DFABytecode>& bytecode, uint32_t index, IntType value)
 {
     RELEASE_ASSERT(index + sizeof(IntType) <= bytecode.size());
     ASSERT_WITH_MESSAGE(!*reinterpret_cast<IntType*>(&bytecode[index]), "Right now we should only be using setBits to overwrite values that were zero as a placeholder.");
@@ -76,24 +80,59 @@
         return sizeof(DFABytecodeInstruction) + sizeof(uint16_t) + sizeof(uint32_t);
     return sizeof(DFABytecodeInstruction) + sizeof(uint32_t);
 }
-    
+
+static DFABytecodeFlagsSize bytecodeFlagsSize(ResourceFlags flags)
+{
+    if (flags <= std::numeric_limits<uint8_t>::max())
+        return DFABytecodeFlagsSize::UInt8;
+    if (flags <= std::numeric_limits<uint16_t>::max())
+        return DFABytecodeFlagsSize::UInt16;
+    RELEASE_ASSERT(flags <= UInt24Max);
+    return DFABytecodeFlagsSize::UInt24;
+}
+
+static DFABytecodeActionSize bytecodeActionSize(uint32_t actionWithoutFlags)
+{
+    if (actionWithoutFlags <= std::numeric_limits<uint8_t>::max())
+        return DFABytecodeActionSize::UInt8;
+    if (actionWithoutFlags <= std::numeric_limits<uint16_t>::max())
+        return DFABytecodeActionSize::UInt16;
+    if (actionWithoutFlags <= UInt24Max)
+        return DFABytecodeActionSize::UInt24;
+    return DFABytecodeActionSize::UInt32;
+}
+
+static void appendVariableLengthUnsignedInteger(Vector<DFABytecode>& bytecode, uint32_t integer)
+{
+    if (integer <= std::numeric_limits<uint8_t>::max())
+        return append<uint8_t>(bytecode, integer);
+    if (integer <= std::numeric_limits<uint16_t>::max())
+        return append<uint16_t>(bytecode, integer);
+    if (integer <= UInt24Max)
+        return append24BitUnsignedInteger(bytecode, integer);
+    return append<uint32_t>(bytecode, integer);
+}
+
 void DFABytecodeCompiler::emitAppendAction(uint64_t action)
 {
+    uint32_t actionWithoutFlags = action;
+    auto actionSize = bytecodeActionSize(actionWithoutFlags);
+    
     // High bits are used to store flags. See compileRuleList.
-    if (action & ActionFlagMask) {
-        if (action & IfConditionFlag)
-            append<DFABytecodeInstruction>(m_bytecode, DFABytecodeInstruction::TestFlagsAndAppendActionWithIfCondition);
-        else
-            append<DFABytecodeInstruction>(m_bytecode, DFABytecodeInstruction::TestFlagsAndAppendAction);
-        append<uint16_t>(m_bytecode, static_cast<uint16_t>(action >> 32));
-        append<uint32_t>(m_bytecode, static_cast<uint32_t>(action));
-    } else {
-        if (action & IfConditionFlag)
-            append<DFABytecodeInstruction>(m_bytecode, DFABytecodeInstruction::AppendActionWithIfCondition);
-        else
-            append<DFABytecodeInstruction>(m_bytecode, DFABytecodeInstruction::AppendAction);
-        append<uint32_t>(m_bytecode, static_cast<uint32_t>(action));
+    if (ResourceFlags flags = (action & ActionFlagMask) >> 32) {
+        auto flagsSize = bytecodeFlagsSize(flags);
+        auto instruction = (action & IfConditionFlag) ? DFABytecodeInstruction::TestFlagsAndAppendActionWithIfCondition : DFABytecodeInstruction::TestFlagsAndAppendAction;
+        ASSERT(!(static_cast<uint8_t>(instruction) & static_cast<uint8_t>(flagsSize) & static_cast<uint8_t>(actionSize)));
+        append<uint8_t>(m_bytecode, static_cast<uint8_t>(instruction) | static_cast<uint8_t>(flagsSize) | static_cast<uint8_t>(actionSize));
+        appendVariableLengthUnsignedInteger(m_bytecode, flags);
+        appendVariableLengthUnsignedInteger(m_bytecode, actionWithoutFlags);
+        return;
     }
+
+    auto instruction = (action & IfConditionFlag) ? DFABytecodeInstruction::AppendActionWithIfCondition : DFABytecodeInstruction::AppendAction;
+    ASSERT(!(static_cast<uint8_t>(instruction) & static_cast<uint8_t>(actionSize)));
+    append<uint8_t>(m_bytecode, static_cast<uint8_t>(instruction) | static_cast<uint8_t>(actionSize));
+    appendVariableLengthUnsignedInteger(m_bytecode, actionWithoutFlags);
 }
 
 int32_t DFABytecodeCompiler::longestPossibleJump(uint32_t instructionLocation, uint32_t sourceNodeIndex, uint32_t destinationNodeIndex)
@@ -119,7 +158,7 @@
     uint32_t jumpLocation = instructionLocation + sizeof(uint8_t);
     int32_t longestPossibleJumpDistance = longestPossibleJump(instructionLocation, sourceNodeIndex, destinationNodeIndex);
     DFABytecodeJumpSize jumpSize = smallestPossibleJumpSize(longestPossibleJumpDistance);
-    append<uint8_t>(m_bytecode, static_cast<uint8_t>(DFABytecodeInstruction::Jump) | jumpSize);
+    append<uint8_t>(m_bytecode, static_cast<uint8_t>(DFABytecodeInstruction::Jump) | static_cast<uint8_t>(jumpSize));
 
     m_linkRecords.append(LinkRecord({jumpSize, longestPossibleJumpDistance, instructionLocation, jumpLocation, destinationNodeIndex}));
     appendZeroes(m_bytecode, jumpSize);
@@ -132,7 +171,7 @@
     int32_t longestPossibleJumpDistance = longestPossibleJump(instructionLocation, sourceNodeIndex, destinationNodeIndex);
     DFABytecodeJumpSize jumpSize = smallestPossibleJumpSize(longestPossibleJumpDistance);
     DFABytecodeInstruction instruction = caseSensitive ? DFABytecodeInstruction::CheckValueCaseSensitive : DFABytecodeInstruction::CheckValueCaseInsensitive;
-    append<uint8_t>(m_bytecode, static_cast<uint8_t>(instruction) | jumpSize);
+    append<uint8_t>(m_bytecode, static_cast<uint8_t>(instruction) | static_cast<uint8_t>(jumpSize));
     append<uint8_t>(m_bytecode, value);
     m_linkRecords.append(LinkRecord({jumpSize, longestPossibleJumpDistance, instructionLocation, jumpLocation, destinationNodeIndex}));
     appendZeroes(m_bytecode, jumpSize);
@@ -147,7 +186,7 @@
     int32_t longestPossibleJumpDistance = longestPossibleJump(instructionLocation, sourceNodeIndex, destinationNodeIndex);
     DFABytecodeJumpSize jumpSize = smallestPossibleJumpSize(longestPossibleJumpDistance);
     DFABytecodeInstruction instruction = caseSensitive ? DFABytecodeInstruction::CheckValueRangeCaseSensitive : DFABytecodeInstruction::CheckValueRangeCaseInsensitive;
-    append<uint8_t>(m_bytecode, static_cast<uint8_t>(instruction) | jumpSize);
+    append<uint8_t>(m_bytecode, static_cast<uint8_t>(instruction) | static_cast<uint8_t>(jumpSize));
     append<uint8_t>(m_bytecode, lowValue);
     append<uint8_t>(m_bytecode, highValue);
     m_linkRecords.append(LinkRecord({jumpSize, longestPossibleJumpDistance, instructionLocation, jumpLocation, destinationNodeIndex}));
@@ -226,7 +265,7 @@
     return jumpTable;
 }
 
-DFABytecodeCompiler::Transitions DFABytecodeCompiler::transitions(const DFANode& node)
+auto DFABytecodeCompiler::transitions(const DFANode& node) -> Transitions
 {
     Transitions transitions;
 
@@ -350,7 +389,7 @@
     ASSERT(jumpTable.min <= jumpTable.max);
 
     uint32_t instructionLocation = m_bytecode.size();
-    DFABytecodeJumpSize jumpSize = Int8;
+    auto jumpSize = DFABytecodeJumpSize::Int8;
     for (uint32_t destinationNodeIndex : jumpTable.destinations) {
         int32_t longestPossibleJumpDistance = longestPossibleJump(instructionLocation, nodeIndex, destinationNodeIndex);
         DFABytecodeJumpSize localJumpSize = smallestPossibleJumpSize(longestPossibleJumpDistance);
@@ -358,7 +397,7 @@
     }
 
     DFABytecodeInstruction instruction = jumpTable.caseSensitive ? DFABytecodeInstruction::JumpTableCaseSensitive : DFABytecodeInstruction::JumpTableCaseInsensitive;
-    append<uint8_t>(m_bytecode, static_cast<uint8_t>(instruction) | jumpSize);
+    append<uint8_t>(m_bytecode, static_cast<uint8_t>(instruction) | static_cast<uint8_t>(jumpSize));
     append<uint8_t>(m_bytecode, jumpTable.min);
     append<uint8_t>(m_bytecode, jumpTable.max);
 
@@ -397,7 +436,7 @@
     if (nodeTransitions.useFallbackTransition)
         size += sizeof(DFABytecodeInstruction::Jump) + sizeof(uint32_t);
     else
-        size += instructionSizeWithArguments(DFABytecodeInstruction::Terminate);
+        size += sizeof(DFABytecodeInstruction::Terminate);
     return size;
 }
 
@@ -466,20 +505,20 @@
         ASSERT(abs(distance) <= abs(linkRecord.longestPossibleJump));
         
         switch (linkRecord.jumpSize) {
-        case Int8:
+        case DFABytecodeJumpSize::Int8:
             RELEASE_ASSERT(distance == static_cast<int8_t>(distance));
             setBits<int8_t>(m_bytecode, linkRecord.jumpLocation, static_cast<int8_t>(distance));
             break;
-        case Int16:
+        case DFABytecodeJumpSize::Int16:
             RELEASE_ASSERT(distance == static_cast<int16_t>(distance));
             setBits<int16_t>(m_bytecode, linkRecord.jumpLocation, static_cast<int16_t>(distance));
             break;
-        case Int24:
+        case DFABytecodeJumpSize::Int24:
             RELEASE_ASSERT(distance >= Int24Min && distance <= Int24Max);
             setBits<uint16_t>(m_bytecode, linkRecord.jumpLocation, static_cast<uint16_t>(distance));
             setBits<int8_t>(m_bytecode, linkRecord.jumpLocation + sizeof(int16_t), static_cast<int8_t>(distance >> 16));
             break;
-        case Int32:
+        case DFABytecodeJumpSize::Int32:
             setBits<int32_t>(m_bytecode, linkRecord.jumpLocation, distance);
             break;
         }
@@ -487,9 +526,7 @@
     
     setBits<DFAHeader>(m_bytecode, startLocation, m_bytecode.size() - startLocation);
 }
-    
-} // namespace ContentExtensions
 
-} // namespace WebCore
+} // namespace WebCore::ContentExtensions
 
 #endif // ENABLE(CONTENT_EXTENSIONS)

Modified: trunk/Source/WebCore/contentextensions/DFABytecodeInterpreter.cpp (286382 => 286383)


--- trunk/Source/WebCore/contentextensions/DFABytecodeInterpreter.cpp	2021-12-01 21:25:07 UTC (rev 286382)
+++ trunk/Source/WebCore/contentextensions/DFABytecodeInterpreter.cpp	2021-12-01 21:31:04 UTC (rev 286383)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2021 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -31,62 +31,155 @@
 
 #if ENABLE(CONTENT_EXTENSIONS)
 
-namespace WebCore {
-    
-namespace ContentExtensions {
+namespace WebCore::ContentExtensions {
 
 template <typename IntType>
-static inline IntType getBits(const DFABytecode* bytecode, uint32_t bytecodeLength, uint32_t index)
+static IntType getBits(Span<const uint8_t> bytecode, uint32_t index)
 {
-    ASSERT_UNUSED(bytecodeLength, index + sizeof(IntType) <= bytecodeLength);
-    return *reinterpret_cast<const IntType*>(&bytecode[index]);
+    ASSERT(index + sizeof(IntType) <= bytecode.size());
+    return *reinterpret_cast<const IntType*>(bytecode.data() + index);
 }
 
-static inline DFABytecodeInstruction getInstruction(const DFABytecode* bytecode, uint32_t bytecodeLength, uint32_t index)
+static uint32_t get24BitsUnsigned(Span<const uint8_t> bytecode, uint32_t index)
 {
-    return static_cast<DFABytecodeInstruction>(getBits<uint8_t>(bytecode, bytecodeLength, index) & DFABytecodeInstructionMask);
+    ASSERT(index + UInt24Size <= bytecode.size());
+    uint32_t highBits = getBits<uint8_t>(bytecode, index + sizeof(uint16_t));
+    uint32_t lowBits = getBits<uint16_t>(bytecode, index);
+    return (highBits << 16) | lowBits;
 }
 
-static inline size_t jumpSizeInBytes(DFABytecodeJumpSize jumpSize)
+static DFABytecodeInstruction getInstruction(Span<const uint8_t> bytecode, uint32_t index)
 {
+    return static_cast<DFABytecodeInstruction>(getBits<uint8_t>(bytecode, index) & DFABytecodeInstructionMask);
+}
+
+static size_t jumpSizeInBytes(DFABytecodeJumpSize jumpSize)
+{
     switch (jumpSize) {
-    case Int8:
+    case DFABytecodeJumpSize::Int8:
         return sizeof(int8_t);
-    case Int16:
+    case DFABytecodeJumpSize::Int16:
         return sizeof(int16_t);
-    case Int24:
-        return sizeof(uint16_t) + sizeof(int8_t);
-    case Int32:
+    case DFABytecodeJumpSize::Int24:
+        return Int24Size;
+    case DFABytecodeJumpSize::Int32:
         return sizeof(int32_t);
-    default:
-        RELEASE_ASSERT_NOT_REACHED();
     }
+    RELEASE_ASSERT_NOT_REACHED();
 }
 
-static inline DFABytecodeJumpSize getJumpSize(const DFABytecode* bytecode, uint32_t bytecodeLength, uint32_t index)
+template<typename T> uint32_t consumeInteger(Span<const uint8_t> bytecode, uint32_t& programCounter)
 {
-    DFABytecodeJumpSize jumpSize = static_cast<DFABytecodeJumpSize>(getBits<uint8_t>(bytecode, bytecodeLength, index) & DFABytecodeJumpSizeMask);
-    ASSERT(jumpSize == DFABytecodeJumpSize::Int32 || jumpSize == DFABytecodeJumpSize::Int24 || jumpSize == DFABytecodeJumpSize::Int16 || jumpSize == DFABytecodeJumpSize::Int8);
+    programCounter += sizeof(T);
+    return getBits<T>(bytecode, programCounter - sizeof(T));
+}
+static uint32_t consume24BitUnsignedInteger(Span<const uint8_t> bytecode, uint32_t& programCounter)
+{
+    programCounter += UInt24Size;
+    return get24BitsUnsigned(bytecode, programCounter - UInt24Size);
+}
+
+static constexpr bool hasFlags(DFABytecodeInstruction instruction)
+{
+    switch (instruction) {
+    case DFABytecodeInstruction::TestFlagsAndAppendAction:
+    case DFABytecodeInstruction::TestFlagsAndAppendActionWithIfCondition:
+        return true;
+    case DFABytecodeInstruction::CheckValueCaseSensitive:
+    case DFABytecodeInstruction::CheckValueCaseInsensitive:
+    case DFABytecodeInstruction::JumpTableCaseInsensitive:
+    case DFABytecodeInstruction::JumpTableCaseSensitive:
+    case DFABytecodeInstruction::CheckValueRangeCaseSensitive:
+    case DFABytecodeInstruction::CheckValueRangeCaseInsensitive:
+    case DFABytecodeInstruction::Jump:
+    case DFABytecodeInstruction::AppendAction:
+    case DFABytecodeInstruction::AppendActionWithIfCondition:
+    case DFABytecodeInstruction::Terminate:
+        break;
+    }
+    return false;
+}
+
+static constexpr bool hasAction(DFABytecodeInstruction instruction)
+{
+    switch (instruction) {
+    case DFABytecodeInstruction::TestFlagsAndAppendAction:
+    case DFABytecodeInstruction::TestFlagsAndAppendActionWithIfCondition:
+    case DFABytecodeInstruction::AppendAction:
+    case DFABytecodeInstruction::AppendActionWithIfCondition:
+        return true;
+    case DFABytecodeInstruction::CheckValueCaseSensitive:
+    case DFABytecodeInstruction::CheckValueCaseInsensitive:
+    case DFABytecodeInstruction::JumpTableCaseInsensitive:
+    case DFABytecodeInstruction::JumpTableCaseSensitive:
+    case DFABytecodeInstruction::CheckValueRangeCaseSensitive:
+    case DFABytecodeInstruction::CheckValueRangeCaseInsensitive:
+    case DFABytecodeInstruction::Jump:
+    case DFABytecodeInstruction::Terminate:
+        break;
+    }
+    return false;
+}
+
+static ResourceFlags consumeResourceFlagsAndInstruction(Span<const uint8_t> bytecode, uint32_t& programCounter)
+{
+    ASSERT_UNUSED(hasFlags, hasFlags(getInstruction(bytecode, programCounter)));
+    switch (static_cast<DFABytecodeFlagsSize>(bytecode[programCounter++] & DFABytecodeFlagsSizeMask)) {
+    case DFABytecodeFlagsSize::UInt8:
+        return consumeInteger<uint8_t>(bytecode, programCounter);
+    case DFABytecodeFlagsSize::UInt16:
+        return consumeInteger<uint16_t>(bytecode, programCounter);
+    case DFABytecodeFlagsSize::UInt24:
+        return consume24BitUnsignedInteger(bytecode, programCounter);
+    }
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
+static uint32_t consumeAction(Span<const uint8_t> bytecode, uint32_t& programCounter, uint32_t instructionLocation)
+{
+    ASSERT_UNUSED(hasAction, hasAction(getInstruction(bytecode, instructionLocation)));
+    ASSERT(programCounter > instructionLocation);
+    switch (static_cast<DFABytecodeActionSize>(bytecode[instructionLocation] & DFABytecodeActionSizeMask)) {
+    case DFABytecodeActionSize::UInt8:
+        return consumeInteger<uint8_t>(bytecode, programCounter);
+    case DFABytecodeActionSize::UInt16:
+        return consumeInteger<uint16_t>(bytecode, programCounter);
+    case DFABytecodeActionSize::UInt24:
+        return consume24BitUnsignedInteger(bytecode, programCounter);
+    case DFABytecodeActionSize::UInt32:
+        return consumeInteger<uint32_t>(bytecode, programCounter);
+    }
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
+static DFABytecodeJumpSize getJumpSize(Span<const uint8_t> bytecode, uint32_t index)
+{
+    auto jumpSize = static_cast<DFABytecodeJumpSize>(getBits<uint8_t>(bytecode, index) & DFABytecodeJumpSizeMask);
+    ASSERT(jumpSize == DFABytecodeJumpSize::Int32
+        || jumpSize == DFABytecodeJumpSize::Int24
+        || jumpSize == DFABytecodeJumpSize::Int16
+        || jumpSize == DFABytecodeJumpSize::Int8);
     return jumpSize;
 }
 
-static inline int32_t getJumpDistance(const DFABytecode* bytecode, uint32_t bytecodeLength, uint32_t index, DFABytecodeJumpSize jumpSize)
+static int32_t getJumpDistance(Span<const uint8_t> bytecode, uint32_t index, DFABytecodeJumpSize jumpSize)
 {
     switch (jumpSize) {
-    case Int8:
-        return getBits<int8_t>(bytecode, bytecodeLength, index);
-    case Int16:
-        return getBits<int16_t>(bytecode, bytecodeLength, index);
-    case Int24:
-        return getBits<uint16_t>(bytecode, bytecodeLength, index) | (static_cast<int32_t>(getBits<int8_t>(bytecode, bytecodeLength, index + sizeof(uint16_t))) << 16);
-    case Int32:
-        return getBits<int32_t>(bytecode, bytecodeLength, index);
-    default:
-        RELEASE_ASSERT_NOT_REACHED();
+    case DFABytecodeJumpSize::Int8:
+        return getBits<int8_t>(bytecode, index);
+    case DFABytecodeJumpSize::Int16:
+        return getBits<int16_t>(bytecode, index);
+    case DFABytecodeJumpSize::Int24:
+        return getBits<uint16_t>(bytecode, index) | (static_cast<int32_t>(getBits<int8_t>(bytecode, index + sizeof(uint16_t))) << 16);
+    case DFABytecodeJumpSize::Int32:
+        return getBits<int32_t>(bytecode, index);
     }
+    RELEASE_ASSERT_NOT_REACHED();
 }
 
-static inline bool matchesCondition(uint64_t actionAndFlags, const DFABytecodeInterpreter::Actions& conditionActions)
+static bool matchesCondition(uint64_t actionAndFlags, const DFABytecodeInterpreter::Actions& conditionActions)
 {
     bool ifCondition = actionAndFlags & IfConditionFlag;
     bool condition = conditionActions.contains(actionAndFlags);
@@ -95,51 +188,48 @@
 
 void DFABytecodeInterpreter::interpretAppendAction(uint32_t& programCounter, Actions& actions, bool ifCondition)
 {
-    ASSERT(getInstruction(m_bytecode, m_bytecodeLength, programCounter) == DFABytecodeInstruction::AppendAction
-        || getInstruction(m_bytecode, m_bytecodeLength, programCounter) == DFABytecodeInstruction::AppendActionWithIfCondition);
-    uint64_t action = "" ? IfConditionFlag : 0) | static_cast<uint64_t>(getBits<uint32_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecodeInstruction)));
+    ASSERT(getInstruction(m_bytecode, programCounter) == DFABytecodeInstruction::AppendAction
+        || getInstruction(m_bytecode, programCounter) == DFABytecodeInstruction::AppendActionWithIfCondition);
+    auto instructionLocation = programCounter++;
+    uint64_t actionWithoutFlags = consumeAction(m_bytecode, programCounter, instructionLocation);
+    uint64_t action = "" ? IfConditionFlag : 0) | actionWithoutFlags;
     if (!m_topURLActions || matchesCondition(action, *m_topURLActions))
         actions.add(action);
-    
-    programCounter += instructionSizeWithArguments(DFABytecodeInstruction::AppendAction);
-    ASSERT(instructionSizeWithArguments(DFABytecodeInstruction::AppendAction) == instructionSizeWithArguments(DFABytecodeInstruction::AppendActionWithIfCondition));
 }
 
-void DFABytecodeInterpreter::interpretTestFlagsAndAppendAction(uint32_t& programCounter, uint16_t flags, Actions& actions, bool ifCondition)
+void DFABytecodeInterpreter::interpretTestFlagsAndAppendAction(uint32_t& programCounter, ResourceFlags flags, Actions& actions, bool ifCondition)
 {
-    ASSERT(getInstruction(m_bytecode, m_bytecodeLength, programCounter) == DFABytecodeInstruction::TestFlagsAndAppendAction
-        || getInstruction(m_bytecode, m_bytecodeLength, programCounter) == DFABytecodeInstruction::TestFlagsAndAppendActionWithIfCondition);
-    uint16_t flagsToCheck = getBits<uint16_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecodeInstruction));
+    auto instructionLocation = programCounter;
+    auto flagsToCheck = consumeResourceFlagsAndInstruction(m_bytecode, programCounter);
 
-    uint16_t loadTypeFlags = flagsToCheck & LoadTypeMask;
-    uint16_t loadContextFlags = flagsToCheck & LoadContextMask;
-    uint16_t resourceTypeFlags = flagsToCheck & ResourceTypeMask;
+    ResourceFlags loadTypeFlags = flagsToCheck & LoadTypeMask;
+    ResourceFlags loadContextFlags = flagsToCheck & LoadContextMask;
+    ResourceFlags resourceTypeFlags = flagsToCheck & ResourceTypeMask;
 
     bool loadTypeMatches = loadTypeFlags ? (loadTypeFlags & flags) : true;
     bool loadContextMatches = loadContextFlags ? (loadContextFlags & flags) : true;
     bool resourceTypeMatches = resourceTypeFlags ? (resourceTypeFlags & flags) : true;
     
+    auto actionWithoutFlags = consumeAction(m_bytecode, programCounter, instructionLocation);
     if (loadTypeMatches && loadContextMatches && resourceTypeMatches) {
-        uint64_t actionAndFlags = (ifCondition ? IfConditionFlag : 0) | (static_cast<uint64_t>(flagsToCheck) << 32) | static_cast<uint64_t>(getBits<uint32_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecodeInstruction) + sizeof(uint16_t)));
+        uint64_t actionAndFlags = (ifCondition ? IfConditionFlag : 0) | (static_cast<uint64_t>(flagsToCheck) << 32) | static_cast<uint64_t>(actionWithoutFlags);
         if (!m_topURLActions || matchesCondition(actionAndFlags, *m_topURLActions))
             actions.add(actionAndFlags);
     }
-    programCounter += instructionSizeWithArguments(DFABytecodeInstruction::TestFlagsAndAppendAction);
-    ASSERT(instructionSizeWithArguments(DFABytecodeInstruction::TestFlagsAndAppendAction) == instructionSizeWithArguments(DFABytecodeInstruction::TestFlagsAndAppendActionWithIfCondition));
 }
 
 template<bool caseSensitive>
 inline void DFABytecodeInterpreter::interpetJumpTable(const char* url, uint32_t& urlIndex, uint32_t& programCounter, bool& urlIndexIsAfterEndOfString)
 {
-    DFABytecodeJumpSize jumpSize = getJumpSize(m_bytecode, m_bytecodeLength, programCounter);
+    DFABytecodeJumpSize jumpSize = getJumpSize(m_bytecode, programCounter);
 
     char character = caseSensitive ? url[urlIndex] : toASCIILower(url[urlIndex]);
-    uint8_t firstCharacter = getBits<uint8_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecodeInstruction));
-    uint8_t lastCharacter = getBits<uint8_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecodeInstruction) + sizeof(uint8_t));
+    uint8_t firstCharacter = getBits<uint8_t>(m_bytecode, programCounter + sizeof(DFABytecodeInstruction));
+    uint8_t lastCharacter = getBits<uint8_t>(m_bytecode, programCounter + sizeof(DFABytecodeInstruction) + sizeof(uint8_t));
     if (character >= firstCharacter && character <= lastCharacter) {
         uint32_t startOffset = programCounter + sizeof(DFABytecodeInstruction) + 2 * sizeof(uint8_t);
         uint32_t jumpLocation = startOffset + (character - firstCharacter) * jumpSizeInBytes(jumpSize);
-        programCounter += getJumpDistance(m_bytecode, m_bytecodeLength, jumpLocation, jumpSize);
+        programCounter += getJumpDistance(m_bytecode, jumpLocation, jumpSize);
         if (!character)
             urlIndexIsAfterEndOfString = true;
         urlIndex++; // This represents an edge in the DFA.
@@ -147,40 +237,41 @@
         programCounter += sizeof(DFABytecodeInstruction) + 2 * sizeof(uint8_t) + jumpSizeInBytes(jumpSize) * (lastCharacter - firstCharacter + 1);
 }
 
-DFABytecodeInterpreter::Actions DFABytecodeInterpreter::actionsMatchingEverything()
+auto DFABytecodeInterpreter::actionsMatchingEverything() -> Actions
 {
     Actions actions;
 
     // DFA header.
-    uint32_t dfaBytecodeLength = getBits<uint32_t>(m_bytecode, m_bytecodeLength, 0);
-    uint32_t programCounter = sizeof(uint32_t);
+    uint32_t dfaBytecodeLength = getBits<uint32_t>(m_bytecode, 0);
+    uint32_t programCounter = sizeof(DFAHeader);
 
     while (programCounter < dfaBytecodeLength) {
-        DFABytecodeInstruction instruction = getInstruction(m_bytecode, m_bytecodeLength, programCounter);
+        DFABytecodeInstruction instruction = getInstruction(m_bytecode, programCounter);
         if (instruction == DFABytecodeInstruction::AppendAction)
             interpretAppendAction(programCounter, actions, false);
         else if (instruction == DFABytecodeInstruction::AppendActionWithIfCondition)
             interpretAppendAction(programCounter, actions, true);
-        else if (instruction == DFABytecodeInstruction::TestFlagsAndAppendAction)
-            programCounter += instructionSizeWithArguments(DFABytecodeInstruction::TestFlagsAndAppendAction);
-        else if (instruction == DFABytecodeInstruction::TestFlagsAndAppendActionWithIfCondition)
-            programCounter += instructionSizeWithArguments(DFABytecodeInstruction::TestFlagsAndAppendActionWithIfCondition);
-        else
+        else if (instruction == DFABytecodeInstruction::TestFlagsAndAppendAction
+            || instruction == DFABytecodeInstruction::TestFlagsAndAppendActionWithIfCondition) {
+            auto programCounterAtInstruction = programCounter;
+            consumeResourceFlagsAndInstruction(m_bytecode, programCounter);
+            consumeAction(m_bytecode, programCounter, programCounterAtInstruction);
+        } else
             break;
     }
     return actions;
 }
     
-DFABytecodeInterpreter::Actions DFABytecodeInterpreter::interpretWithConditions(const CString& urlCString, uint16_t flags, const DFABytecodeInterpreter::Actions& topURLActions)
+auto DFABytecodeInterpreter::interpretWithConditions(const CString& urlCString, ResourceFlags flags, const Actions& topURLActions) -> Actions
 {
     ASSERT(!m_topURLActions);
     m_topURLActions = &topURLActions;
-    DFABytecodeInterpreter::Actions actions = interpret(urlCString, flags);
+    auto actions = interpret(urlCString, flags);
     m_topURLActions = nullptr;
     return actions;
 }
 
-DFABytecodeInterpreter::Actions DFABytecodeInterpreter::interpret(const CString& urlCString, uint16_t flags)
+auto DFABytecodeInterpreter::interpret(const CString& urlCString, ResourceFlags flags) -> Actions
 {
     const char* url = ""
     ASSERT(url);
@@ -188,22 +279,21 @@
     Actions actions;
     
     uint32_t programCounter = 0;
-    while (programCounter < m_bytecodeLength) {
+    while (programCounter < m_bytecode.size()) {
 
         // DFA header.
         uint32_t dfaStart = programCounter;
-        uint32_t dfaBytecodeLength = getBits<uint32_t>(m_bytecode, m_bytecodeLength, programCounter);
+        uint32_t dfaBytecodeLength = getBits<uint32_t>(m_bytecode, programCounter);
         programCounter += sizeof(uint32_t);
 
         // Skip the actions without flags on the DFA root. These are accessed via actionsMatchingEverything.
         if (!dfaStart) {
             while (programCounter < dfaBytecodeLength) {
-                DFABytecodeInstruction instruction = getInstruction(m_bytecode, m_bytecodeLength, programCounter);
-                if (instruction == DFABytecodeInstruction::AppendAction)
-                    programCounter += instructionSizeWithArguments(DFABytecodeInstruction::AppendAction);
-                else if (instruction == DFABytecodeInstruction::AppendActionWithIfCondition)
-                    programCounter += instructionSizeWithArguments(DFABytecodeInstruction::AppendActionWithIfCondition);
-                else if (instruction == DFABytecodeInstruction::TestFlagsAndAppendAction)
+                DFABytecodeInstruction instruction = getInstruction(m_bytecode, programCounter);
+                if (instruction == DFABytecodeInstruction::AppendAction || instruction == DFABytecodeInstruction::AppendActionWithIfCondition) {
+                    auto instructionLocation = programCounter++;
+                    consumeAction(m_bytecode, programCounter, instructionLocation);
+                } else if (instruction == DFABytecodeInstruction::TestFlagsAndAppendAction)
                     interpretTestFlagsAndAppendAction(programCounter, flags, actions, false);
                 else if (instruction == DFABytecodeInstruction::TestFlagsAndAppendActionWithIfCondition)
                     interpretTestFlagsAndAppendAction(programCounter, flags, actions, true);
@@ -210,13 +300,13 @@
                 else
                     break;
             }
-            if (programCounter >= m_bytecodeLength)
+            if (programCounter >= m_bytecode.size())
                 return actions;
         } else {
-            ASSERT_WITH_MESSAGE(getInstruction(m_bytecode, m_bytecodeLength, programCounter) != DFABytecodeInstruction::AppendAction
-                && getInstruction(m_bytecode, m_bytecodeLength, programCounter) != DFABytecodeInstruction::AppendActionWithIfCondition
-                && getInstruction(m_bytecode, m_bytecodeLength, programCounter) != DFABytecodeInstruction::TestFlagsAndAppendAction
-                && getInstruction(m_bytecode, m_bytecodeLength, programCounter) != DFABytecodeInstruction::TestFlagsAndAppendActionWithIfCondition,
+            ASSERT_WITH_MESSAGE(getInstruction(m_bytecode, programCounter) != DFABytecodeInstruction::AppendAction
+                && getInstruction(m_bytecode, programCounter) != DFABytecodeInstruction::AppendActionWithIfCondition
+                && getInstruction(m_bytecode, programCounter) != DFABytecodeInstruction::TestFlagsAndAppendAction
+                && getInstruction(m_bytecode, programCounter) != DFABytecodeInstruction::TestFlagsAndAppendActionWithIfCondition,
                 "Triggers that match everything should only be in the first DFA.");
         }
         
@@ -225,8 +315,8 @@
         uint32_t urlIndex = 0;
         bool urlIndexIsAfterEndOfString = false;
         while (true) {
-            ASSERT(programCounter <= m_bytecodeLength);
-            switch (getInstruction(m_bytecode, m_bytecodeLength, programCounter)) {
+            ASSERT(programCounter <= m_bytecode.size());
+            switch (getInstruction(m_bytecode, programCounter)) {
 
             case DFABytecodeInstruction::Terminate:
                 goto nextDFA;
@@ -237,10 +327,10 @@
 
                 // Check to see if the next character in the url is the value stored with the bytecode.
                 char character = url[urlIndex];
-                DFABytecodeJumpSize jumpSize = getJumpSize(m_bytecode, m_bytecodeLength, programCounter);
-                if (character == getBits<uint8_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecodeInstruction))) {
+                DFABytecodeJumpSize jumpSize = getJumpSize(m_bytecode, programCounter);
+                if (character == getBits<uint8_t>(m_bytecode, programCounter + sizeof(DFABytecodeInstruction))) {
                     uint32_t jumpLocation = programCounter + sizeof(DFABytecodeInstruction) + sizeof(uint8_t);
-                    programCounter += getJumpDistance(m_bytecode, m_bytecodeLength, jumpLocation, jumpSize);
+                    programCounter += getJumpDistance(m_bytecode, jumpLocation, jumpSize);
                     if (!character)
                         urlIndexIsAfterEndOfString = true;
                     urlIndex++; // This represents an edge in the DFA.
@@ -255,10 +345,10 @@
 
                 // Check to see if the next character in the url is the value stored with the bytecode.
                 char character = toASCIILower(url[urlIndex]);
-                DFABytecodeJumpSize jumpSize = getJumpSize(m_bytecode, m_bytecodeLength, programCounter);
-                if (character == getBits<uint8_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecodeInstruction))) {
+                DFABytecodeJumpSize jumpSize = getJumpSize(m_bytecode, programCounter);
+                if (character == getBits<uint8_t>(m_bytecode, programCounter + sizeof(DFABytecodeInstruction))) {
                     uint32_t jumpLocation = programCounter + sizeof(DFABytecodeInstruction) + sizeof(uint8_t);
-                    programCounter += getJumpDistance(m_bytecode, m_bytecodeLength, jumpLocation, jumpSize);
+                    programCounter += getJumpDistance(m_bytecode, jumpLocation, jumpSize);
                     if (!character)
                         urlIndexIsAfterEndOfString = true;
                     urlIndex++; // This represents an edge in the DFA.
@@ -285,11 +375,11 @@
                     goto nextDFA;
                 
                 char character = url[urlIndex];
-                DFABytecodeJumpSize jumpSize = getJumpSize(m_bytecode, m_bytecodeLength, programCounter);
-                if (character >= getBits<uint8_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecodeInstruction))
-                    && character <= getBits<uint8_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecodeInstruction) + sizeof(uint8_t))) {
+                DFABytecodeJumpSize jumpSize = getJumpSize(m_bytecode, programCounter);
+                if (character >= getBits<uint8_t>(m_bytecode, programCounter + sizeof(DFABytecodeInstruction))
+                    && character <= getBits<uint8_t>(m_bytecode, programCounter + sizeof(DFABytecodeInstruction) + sizeof(uint8_t))) {
                     uint32_t jumpLocation = programCounter + sizeof(DFABytecodeInstruction) + 2 * sizeof(uint8_t);
-                    programCounter += getJumpDistance(m_bytecode, m_bytecodeLength, jumpLocation, jumpSize);
+                    programCounter += getJumpDistance(m_bytecode, jumpLocation, jumpSize);
                     if (!character)
                         urlIndexIsAfterEndOfString = true;
                     urlIndex++; // This represents an edge in the DFA.
@@ -303,11 +393,11 @@
                     goto nextDFA;
                 
                 char character = toASCIILower(url[urlIndex]);
-                DFABytecodeJumpSize jumpSize = getJumpSize(m_bytecode, m_bytecodeLength, programCounter);
-                if (character >= getBits<uint8_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecodeInstruction))
-                    && character <= getBits<uint8_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecodeInstruction) + sizeof(uint8_t))) {
+                DFABytecodeJumpSize jumpSize = getJumpSize(m_bytecode, programCounter);
+                if (character >= getBits<uint8_t>(m_bytecode, programCounter + sizeof(DFABytecodeInstruction))
+                    && character <= getBits<uint8_t>(m_bytecode, programCounter + sizeof(DFABytecodeInstruction) + sizeof(uint8_t))) {
                     uint32_t jumpLocation = programCounter + sizeof(DFABytecodeInstruction) + 2 * sizeof(uint8_t);
-                    programCounter += getJumpDistance(m_bytecode, m_bytecodeLength, jumpLocation, jumpSize);
+                    programCounter += getJumpDistance(m_bytecode, jumpLocation, jumpSize);
                     if (!character)
                         urlIndexIsAfterEndOfString = true;
                     urlIndex++; // This represents an edge in the DFA.
@@ -321,8 +411,8 @@
                     goto nextDFA;
                 
                 uint32_t jumpLocation = programCounter + sizeof(DFABytecodeInstruction);
-                DFABytecodeJumpSize jumpSize = getJumpSize(m_bytecode, m_bytecodeLength, programCounter);
-                programCounter += getJumpDistance(m_bytecode, m_bytecodeLength, jumpLocation, jumpSize);
+                DFABytecodeJumpSize jumpSize = getJumpSize(m_bytecode, programCounter);
+                programCounter += getJumpDistance(m_bytecode, jumpLocation, jumpSize);
                 urlIndex++; // This represents an edge in the DFA.
                 break;
             }
@@ -357,8 +447,6 @@
     return actions;
 }
 
-} // namespace ContentExtensions
-    
-} // namespace WebCore
+} // namespace WebCore::ContentExtensions
 
 #endif // ENABLE(CONTENT_EXTENSIONS)

Modified: trunk/Source/WebCore/contentextensions/DFABytecodeInterpreter.h (286382 => 286383)


--- trunk/Source/WebCore/contentextensions/DFABytecodeInterpreter.h	2021-12-01 21:25:07 UTC (rev 286382)
+++ trunk/Source/WebCore/contentextensions/DFABytecodeInterpreter.h	2021-12-01 21:31:04 UTC (rev 286383)
@@ -33,37 +33,30 @@
 #include <wtf/DataLog.h>
 #include <wtf/HashSet.h>
 
-namespace WebCore {
-    
-namespace ContentExtensions {
+namespace WebCore::ContentExtensions {
 
-class WEBCORE_EXPORT DFABytecodeInterpreter {
+class DFABytecodeInterpreter {
 public:
-    DFABytecodeInterpreter(const DFABytecode* bytecode, unsigned bytecodeLength)
-        : m_bytecode(bytecode)
-        , m_bytecodeLength(bytecodeLength)
-    {
-    }
-    
-    typedef HashSet<uint64_t, DefaultHash<uint64_t>, WTF::UnsignedWithZeroKeyHashTraits<uint64_t>> Actions;
-    
-    Actions interpret(const CString&, uint16_t flags);
-    Actions interpretWithConditions(const CString&, uint16_t flags, const DFABytecodeInterpreter::Actions& conditionActions);
+    DFABytecodeInterpreter(Span<const uint8_t> bytecode)
+        : m_bytecode(bytecode) { }
+
+    using Actions = HashSet<uint64_t, DefaultHash<uint64_t>, WTF::UnsignedWithZeroKeyHashTraits<uint64_t>>;
+
+    WEBCORE_EXPORT Actions interpret(const CString&, ResourceFlags);
+    Actions interpretWithConditions(const CString&, ResourceFlags, const Actions& conditionActions);
     Actions actionsMatchingEverything();
 
 private:
     void interpretAppendAction(unsigned& programCounter, Actions&, bool ifCondition);
-    void interpretTestFlagsAndAppendAction(unsigned& programCounter, uint16_t flags, Actions&, bool ifCondition);
+    void interpretTestFlagsAndAppendAction(unsigned& programCounter, ResourceFlags, Actions&, bool ifCondition);
 
     template<bool caseSensitive>
     void interpetJumpTable(const char* url, uint32_t& urlIndex, uint32_t& programCounter, bool& urlIndexIsAfterEndOfString);
 
-    const DFABytecode* m_bytecode;
-    const unsigned m_bytecodeLength;
+    const Span<const uint8_t> m_bytecode;
     const DFABytecodeInterpreter::Actions* m_topURLActions { nullptr };
 };
 
-} // namespace ContentExtensions    
-} // namespace WebCore
+} // namespace WebCore::ContentExtensions
 
 #endif // ENABLE(CONTENT_EXTENSIONS)

Modified: trunk/Source/WebCore/loader/PingLoader.cpp (286382 => 286383)


--- trunk/Source/WebCore/loader/PingLoader.cpp	2021-12-01 21:25:07 UTC (rev 286382)
+++ trunk/Source/WebCore/loader/PingLoader.cpp	2021-12-01 21:31:04 UTC (rev 286383)
@@ -159,7 +159,7 @@
 
     ResourceRequest request(reportURL);
 #if ENABLE(CONTENT_EXTENSIONS)
-    if (processContentRuleListsForLoad(frame, request, ContentExtensions::ResourceType::Other))
+    if (processContentRuleListsForLoad(frame, request, ContentExtensions::ResourceType::CSPReport))
         return;
 #endif
 

Modified: trunk/Source/WebCore/loader/ResourceLoadInfo.cpp (286382 => 286383)


--- trunk/Source/WebCore/loader/ResourceLoadInfo.cpp	2021-12-01 21:25:07 UTC (rev 286382)
+++ trunk/Source/WebCore/loader/ResourceLoadInfo.cpp	2021-12-01 21:31:04 UTC (rev 286383)
@@ -32,8 +32,7 @@
 #include "RegistrableDomain.h"
 #include "SecurityOrigin.h"
 
-namespace WebCore {
-namespace ContentExtensions {
+namespace WebCore::ContentExtensions {
 
 OptionSet<ResourceType> toResourceType(CachedResource::Type type, ResourceRequestBase::Requester requester)
 {
@@ -98,13 +97,13 @@
     if (name == "font")
         return { ResourceType::Font };
     if (name == "raw")
-        return {{ ResourceType::Fetch, ResourceType::WebSocket, ResourceType::Other, ResourceType::Ping }};
+        return { { ResourceType::Fetch, ResourceType::WebSocket, ResourceType::Other, ResourceType::Ping } };
     if (name == "websocket")
         return { ResourceType::WebSocket };
     if (name == "fetch")
         return { ResourceType::Fetch };
     if (name == "other")
-        return {{ ResourceType::Other, ResourceType::Ping }};
+        return { { ResourceType::Other, ResourceType::Ping, ResourceType::CSPReport } };
     if (name == "svg-document")
         return { ResourceType::SVGDocument };
     if (name == "media")
@@ -113,6 +112,8 @@
         return { ResourceType::Popup };
     if (name == "ping")
         return { ResourceType::Ping };
+    if (name == "csp-report")
+        return { ResourceType::CSPReport };
     return std::nullopt;
 }
 
@@ -149,7 +150,6 @@
     return flags;
 }
 
-} // namespace ContentExtensions
-} // namespace WebCore
+} // namespace WebCore::ContentExtensions
 
 #endif // ENABLE(CONTENT_EXTENSIONS)

Modified: trunk/Source/WebCore/loader/ResourceLoadInfo.h (286382 => 286383)


--- trunk/Source/WebCore/loader/ResourceLoadInfo.h	2021-12-01 21:25:07 UTC (rev 286382)
+++ trunk/Source/WebCore/loader/ResourceLoadInfo.h	2021-12-01 21:31:04 UTC (rev 286383)
@@ -31,10 +31,9 @@
 #include <wtf/OptionSet.h>
 #include <wtf/URL.h>
 
-namespace WebCore {
-namespace ContentExtensions {
+namespace WebCore::ContentExtensions {
 
-enum class ResourceType : uint16_t {
+enum class ResourceType : uint32_t {
     Document = 0x0001,
     Image = 0x0002,
     StyleSheet = 0x0004,
@@ -47,36 +46,37 @@
     Fetch = 0x0200,
     WebSocket = 0x0400,
     Other = 0x0800,
+    CSPReport = 0x10000,
 };
-const uint16_t ResourceTypeMask = 0x0FFF;
+static constexpr uint32_t ResourceTypeMask = 0x10FFF;
 
-enum class LoadType : uint16_t {
+enum class LoadType : uint32_t {
     FirstParty = 0x1000,
     ThirdParty = 0x2000,
 };
-const uint16_t LoadTypeMask = 0x3000;
+static constexpr uint32_t LoadTypeMask = 0x3000;
 
-enum class LoadContext : uint16_t {
+enum class LoadContext : uint32_t {
     TopFrame = 0x4000,
     ChildFrame = 0x8000,
 };
-const uint16_t LoadContextMask = 0xC000;
+static constexpr uint32_t LoadContextMask = 0xC000;
 
-static_assert(!(ResourceTypeMask & LoadTypeMask), "ResourceTypeMask and LoadTypeMask should be mutually exclusive because they are stored in the same uint16_t");
-static_assert(!(ResourceTypeMask & LoadContextMask), "ResourceTypeMask and LoadContextMask should be mutually exclusive because they are stored in the same uint16_t");
-static_assert(!(LoadContextMask & LoadTypeMask), "LoadContextMask and LoadTypeMask should be mutually exclusive because they are stored in the same uint16_t");
+static_assert(!(ResourceTypeMask & LoadTypeMask), "ResourceTypeMask and LoadTypeMask should be mutually exclusive because they are stored in the same uint32_t");
+static_assert(!(ResourceTypeMask & LoadContextMask), "ResourceTypeMask and LoadContextMask should be mutually exclusive because they are stored in the same uint32_t");
+static_assert(!(LoadContextMask & LoadTypeMask), "LoadContextMask and LoadTypeMask should be mutually exclusive because they are stored in the same uint32_t");
 
-typedef uint16_t ResourceFlags;
+using ResourceFlags = uint32_t;
 
 // The first 32 bits of a uint64_t action are used for the action location.
-// The next 16 bits are used for the flags (ResourceType and LoadType).
+// The next 24 bits are used for the flags (ResourceType and LoadType).
 // The next bit is used to mark actions that are from a rule with an if-domain.
 //     Actions from rules with unless-domain conditions are distinguished from
 //     rules with if-domain conditions by not having this bit set.
 //     Actions from rules with no conditions are put in the DFA without conditions.
 // The values -1 and -2 are used for removed and empty values in HashTables.
-const uint64_t ActionFlagMask = 0x0000FFFF00000000;
-const uint64_t IfConditionFlag = 0x0001000000000000;
+static constexpr uint64_t ActionFlagMask = 0x00FFFFFF00000000;
+static constexpr uint64_t IfConditionFlag = 0x0100000000000000;
 
 OptionSet<ResourceType> toResourceType(CachedResource::Type, ResourceRequestBase::Requester);
 std::optional<OptionSet<ResourceType>> readResourceType(StringView);
@@ -93,7 +93,6 @@
     ResourceFlags getResourceFlags() const;
 };
 
-} // namespace ContentExtensions
-} // namespace WebCore
+} // namespace WebCore::ContentExtensions
 
 #endif

Modified: trunk/Tools/ChangeLog (286382 => 286383)


--- trunk/Tools/ChangeLog	2021-12-01 21:25:07 UTC (rev 286382)
+++ trunk/Tools/ChangeLog	2021-12-01 21:31:04 UTC (rev 286383)
@@ -1,3 +1,17 @@
+2021-12-01  Alex Christensen  <[email protected]>
+
+        Add csp-report resource type to WKContentRuleList
+        https://bugs.webkit.org/show_bug.cgi?id=233675
+        <rdar://71869893>
+
+        Reviewed by Tim Hatcher.
+
+        * TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp:
+        (TestWebKitAPI::compareContents):
+        (TestWebKitAPI::TEST_F):
+        * TestWebKitAPI/Tests/WebKitCocoa/ContentRuleListNotification.mm:
+        (TEST):
+
 2021-12-01  Ryan Haddad  <[email protected]>
 
         [ iOS ] TestWebKitAPI.ApplicationManifest.IconCoding is a constant failure

Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp (286382 => 286383)


--- trunk/Tools/TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp	2021-12-01 21:25:07 UTC (rev 286382)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp	2021-12-01 21:31:04 UTC (rev 286383)
@@ -540,7 +540,7 @@
     testRequest(backend, mainDocumentRequest("http://foo.orgg/"), { variantIndex<ContentExtensions::BlockLoadAction> });
 }
 
-static void compareContents(const ContentExtensions::DFABytecodeInterpreter::Actions& a, const Vector<uint64_t>& b)
+static void compareContents(const DFABytecodeInterpreter::Actions& a, const Vector<uint64_t>& b)
 {
     EXPECT_EQ(a.size(), b.size());
     for (unsigned i = 0; i < b.size(); ++i)
@@ -562,7 +562,7 @@
     Vector<ContentExtensions::DFABytecode> bytecode;
     ContentExtensions::DFABytecodeCompiler compiler(dfa, bytecode);
     compiler.compile();
-    ContentExtensions::DFABytecodeInterpreter interpreter(bytecode.data(), bytecode.size());
+    DFABytecodeInterpreter interpreter({ bytecode.data(), bytecode.size() });
     compareContents(interpreter.interpret("foo.org", 0), { 0 });
     compareContents(interpreter.interpret("ba.org", 0), { 0 });
     compareContents(interpreter.interpret("bar.org", 0), { });
@@ -588,7 +588,7 @@
     Vector<ContentExtensions::DFABytecode> bytecode;
     ContentExtensions::DFABytecodeCompiler compiler(dfa, bytecode);
     compiler.compile();
-    ContentExtensions::DFABytecodeInterpreter interpreter(bytecode.data(), bytecode.size());
+    DFABytecodeInterpreter interpreter({ bytecode.data(), bytecode.size() });
     compareContents(interpreter.interpret("foo.org", 0), { 0 });
     compareContents(interpreter.interpret("ba.org", 0), { 1 });
     compareContents(interpreter.interpret("bar.org", 0), { });
@@ -971,9 +971,9 @@
     ASSERT_EQ(sequenceInstances(data.actions, "GGG"), 1);
 
     ASSERT_EQ(data.actions.size(), 78u);
-    ASSERT_EQ(data.filtersWithoutConditions.size(),  313u);
-    ASSERT_EQ(data.filtersWithConditions.size(),  5u);
-    ASSERT_EQ(data.topURLFilters.size(),  5u);
+    ASSERT_EQ(data.filtersWithoutConditions.size(), 288u);
+    ASSERT_EQ(data.filtersWithConditions.size(), 5u);
+    ASSERT_EQ(data.topURLFilters.size(), 5u);
     ASSERT_FALSE(data.conditionsApplyOnlyToDomain);
 
     auto extensionWithFlags = InMemoryCompiledContentExtension::create("["
@@ -1108,7 +1108,7 @@
     Vector<ContentExtensions::DFABytecode> bytecode;
     ContentExtensions::DFABytecodeCompiler compiler(dfa, bytecode);
     compiler.compile();
-    ContentExtensions::DFABytecodeInterpreter interpreter(bytecode.data(), bytecode.size());
+    DFABytecodeInterpreter interpreter({ bytecode.data(), bytecode.size() });
     compareContents(interpreter.interpret("eb", 0), { });
     compareContents(interpreter.interpret("we", 0), { });
     compareContents(interpreter.interpret("weeb", 0), { });
@@ -1267,7 +1267,7 @@
         combinedBytecode.appendVector(bytecode);
     }
     
-    ContentExtensions::DFABytecodeInterpreter interpreter(&combinedBytecode[0], combinedBytecode.size());
+    DFABytecodeInterpreter interpreter({ combinedBytecode.data(), combinedBytecode.size() });
     
     patternId = 0;
     for (char c1 = 'A'; c1 <= 'Z'; ++c1) {
@@ -1708,7 +1708,7 @@
             combinedBytecode.appendVector(bytecode);
         }
         
-        ContentExtensions::DFABytecodeInterpreter interpreter(&combinedBytecode[0], combinedBytecode.size());
+        DFABytecodeInterpreter interpreter({ combinedBytecode.data(), combinedBytecode.size() });
         
         EXPECT_EQ(interpreter.interpret("ABBBX", 0).size(), 1ull);
         EXPECT_EQ(interpreter.interpret("ACCCX", 0).size(), 1ull);

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ContentRuleListNotification.mm (286382 => 286383)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ContentRuleListNotification.mm	2021-12-01 21:25:07 UTC (rev 286382)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ContentRuleListNotification.mm	2021-12-01 21:31:04 UTC (rev 286383)
@@ -416,6 +416,26 @@
     EXPECT_WK_STREQ([webView _test_waitForAlert], "iframe fetched successfully");
 }
 
+TEST(ContentRuleList, CSPReport)
+{
+    TestWebKitAPI::HTTPServer server({ { "/", { {
+        { "Content-Security-Policy", "frame-src 'none'; report-uri resources/save-report.py" }
+    }, "<iframe src="" } } });
+
+    auto configuration = adoptNS([WKWebViewConfiguration new]);
+    [[configuration userContentController] addContentRuleList:makeContentRuleList(@"[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\".*\",\"resource-type\":[\"csp-report\"]}}]").get()];
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSZeroRect configuration:configuration.get()]);
+    auto delegate = adoptNS([ContentRuleListNotificationDelegate new]);
+    [webView setNavigationDelegate:delegate.get()];
+    [webView loadRequest:server.request()];
+    while (notificationList.isEmpty())
+        TestWebKitAPI::Util::spinRunLoop();
+
+    URL expectedURL = server.request().URL;
+    expectedURL.setPath("/resources/save-report.py");
+    EXPECT_STREQ(expectedURL.string().utf8().data(), notificationList.first().url.utf8().data());
+}
+
 TEST(ContentRuleList, LegacyVersionAndName)
 {
     NSString *directory = [NSTemporaryDirectory() stringByAppendingPathComponent:@"ContentRuleListTestDirectory"];

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKContentExtensionStore.mm (286382 => 286383)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKContentExtensionStore.mm	2021-12-01 21:25:07 UTC (rev 286382)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKContentExtensionStore.mm	2021-12-01 21:31:04 UTC (rev 286383)
@@ -252,7 +252,7 @@
 
     NSData *data = "" dataWithContentsOfURL:[tempDir URLByAppendingPathComponent:fileName]];
     EXPECT_NOT_NULL(data);
-    EXPECT_EQ(data.length, 228u);
+    EXPECT_EQ(data.length, 225u);
     
     __block bool doneCheckingSource = false;
     [store _getContentRuleListSourceForIdentifier:identifier completionHandler:^(NSString *source) {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to