Vector<Action> ContentExtensionsBackend::actionsForResourceLoad(const ResourceLoadInfo& resourceLoadInfo) const { #if CONTENT_EXTENSIONS_PERFORMANCE_REPORTING double addedTimeStart = monotonicallyIncreasingTime(); #endif if (resourceLoadInfo.resourceURL.protocolIsData()) return Vector<Action>(); const String& urlString = resourceLoadInfo.resourceURL.string(); ASSERT_WITH_MESSAGE(urlString.containsOnlyASCII(), "A decoded URL should only contain ASCII characters. The matching algorithm assumes the input is ASCII."); const CString& urlCString = urlString.utf8(); Vector<Action> finalActions; ResourceFlags flags = resourceLoadInfo.getResourceFlags(); for (auto& contentExtension : m_contentExtensions.values()) { RELEASE_ASSERT(contentExtension); const CompiledContentExtension& compiledExtension = contentExtension->compiledExtension(); DFABytecodeInterpreter withoutDomainsInterpreter(compiledExtension.filtersWithoutDomainsBytecode(), compiledExtension.filtersWithoutDomainsBytecodeLength()); DFABytecodeInterpreter::Actions withoutDomainsActions = withoutDomainsInterpreter.interpret(urlCString, flags); String domain = resourceLoadInfo.mainDocumentURL.host(); DFABytecodeInterpreter withDomainsInterpreter(compiledExtension.filtersWithDomainsBytecode(), compiledExtension.filtersWithDomainsBytecodeLength()); DFABytecodeInterpreter::Actions withDomainsActions = withDomainsInterpreter.interpretWithDomains(urlCString, flags, contentExtension->cachedDomainActions(domain)); const SerializedActionByte* actions = compiledExtension.actions(); const unsigned actionsLength = compiledExtension.actionsLength(); bool sawIgnorePreviousRules = false; const Vector<uint32_t>& universalWithDomains = contentExtension->universalActionsWithDomains(domain); const Vector<uint32_t>& universalWithoutDomains = contentExtension->universalActionsWithoutDomains(); if (!withoutDomainsActions.isEmpty() || !withDomainsActions.isEmpty() || !universalWithDomains.isEmpty() || !universalWithoutDomains.isEmpty()) { Vector<uint32_t> actionLocations; actionLocations.reserveInitialCapacity(withoutDomainsActions.size() + withDomainsActions.size() + universalWithoutDomains.size() + universalWithDomains.size()); for (uint64_t actionLocation : withoutDomainsActions) actionLocations.uncheckedAppend(static_cast<uint32_t>(actionLocation)); for (uint64_t actionLocation : withDomainsActions) actionLocations.uncheckedAppend(static_cast<uint32_t>(actionLocation)); for (uint32_t actionLocation : universalWithoutDomains) actionLocations.uncheckedAppend(actionLocation); for (uint32_t actionLocation : universalWithDomains) actionLocations.uncheckedAppend(actionLocation); std::sort(actionLocations.begin(), actionLocations.end()); // Add actions in reverse order to properly deal with IgnorePreviousRules. for (unsigned i = actionLocations.size(); i; i--) { Action action = Action::deserialize(actions, actionsLength, actionLocations[i - 1]); action.setExtensionIdentifier(contentExtension->identifier()); if (action.type() == ActionType::IgnorePreviousRules) { sawIgnorePreviousRules = true; break; } finalActions.append(action); } } if (!sawIgnorePreviousRules) { finalActions.append(Action(ActionType::CSSDisplayNoneStyleSheet, contentExtension->identifier())); finalActions.last().setExtensionIdentifier(contentExtension->identifier()); } } #if CONTENT_EXTENSIONS_PERFORMANCE_REPORTING double addedTimeEnd = monotonicallyIncreasingTime(); dataLogF("Time added: %f microseconds %s \n", (addedTimeEnd - addedTimeStart) * 1.0e6, resourceLoadInfo.resourceURL.string().utf8().data()); #endif return finalActions; }
Vector<Action> ContentExtensionsBackend::actionsForResourceLoad(const ResourceLoadInfo& resourceLoadInfo) const { #if CONTENT_EXTENSIONS_PERFORMANCE_REPORTING double addedTimeStart = monotonicallyIncreasingTime(); #endif if (resourceLoadInfo.resourceURL.protocolIsData()) return Vector<Action>(); const String& urlString = resourceLoadInfo.resourceURL.string(); ASSERT_WITH_MESSAGE(urlString.containsOnlyASCII(), "A decoded URL should only contain ASCII characters. The matching algorithm assumes the input is ASCII."); const CString& urlCString = urlString.utf8(); Vector<Action> finalActions; ResourceFlags flags = resourceLoadInfo.getResourceFlags(); for (auto& contentExtension : m_contentExtensions.values()) { RELEASE_ASSERT(contentExtension); const CompiledContentExtension& compiledExtension = contentExtension->compiledExtension(); // FIXME: These should use a different Vector<bool> to keep track of which memory pages are used when doing memory reporting. Or just remove the memory reporting completely. DFABytecodeInterpreter withoutDomainsInterpreter(compiledExtension.filtersWithoutDomainsBytecode(), compiledExtension.filtersWithoutDomainsBytecodeLength(), contentExtension->m_pagesUsed); DFABytecodeInterpreter::Actions triggeredActions = withoutDomainsInterpreter.interpret(urlCString, flags); // Check to see if there are any actions triggered with if- or unless-domain and check the domain if there are. DFABytecodeInterpreter withDomainsInterpreter(compiledExtension.filtersWithDomainsBytecode(), compiledExtension.filtersWithDomainsBytecodeLength(), contentExtension->m_pagesUsed); DFABytecodeInterpreter::Actions withDomainsPossibleActions = withDomainsInterpreter.interpret(urlCString, flags); if (!withDomainsPossibleActions.isEmpty()) { DFABytecodeInterpreter domainsInterpreter(compiledExtension.domainFiltersBytecode(), compiledExtension.domainFiltersBytecodeLength(), contentExtension->m_pagesUsed); DFABytecodeInterpreter::Actions domainsActions = domainsInterpreter.interpret(resourceLoadInfo.mainDocumentURL.host().utf8(), flags); DFABytecodeInterpreter::Actions ifDomainActions; DFABytecodeInterpreter::Actions unlessDomainActions; for (uint64_t action : domainsActions) { if (action & IfDomainFlag) ifDomainActions.add(action); else unlessDomainActions.add(action); } for (uint64_t action : withDomainsPossibleActions) { if (ifDomainActions.contains(action)) { // If an if-domain trigger matches, add the action. ASSERT(action & IfDomainFlag); triggeredActions.add(action & ~IfDomainFlag); } else if (!(action & IfDomainFlag) && !unlessDomainActions.contains(action)) { // If this action did not need an if-domain, it must have been an unless-domain rule. // Add the action unless it matched an unless-domain trigger. triggeredActions.add(action); } } } const SerializedActionByte* actions = compiledExtension.actions(); const unsigned actionsLength = compiledExtension.actionsLength(); bool sawIgnorePreviousRules = false; if (!triggeredActions.isEmpty()) { Vector<unsigned> actionLocations; actionLocations.reserveInitialCapacity(triggeredActions.size()); for (auto actionLocation : triggeredActions) actionLocations.append(static_cast<unsigned>(actionLocation)); std::sort(actionLocations.begin(), actionLocations.end()); // Add actions in reverse order to properly deal with IgnorePreviousRules. for (unsigned i = actionLocations.size(); i; i--) { Action action = Action::deserialize(actions, actionsLength, actionLocations[i - 1]); action.setExtensionIdentifier(contentExtension->identifier()); if (action.type() == ActionType::IgnorePreviousRules) { sawIgnorePreviousRules = true; break; } finalActions.append(action); } } if (!sawIgnorePreviousRules) { finalActions.append(Action(ActionType::CSSDisplayNoneStyleSheet, contentExtension->identifier())); finalActions.last().setExtensionIdentifier(contentExtension->identifier()); } } #if CONTENT_EXTENSIONS_PERFORMANCE_REPORTING double addedTimeEnd = monotonicallyIncreasingTime(); WTFLogAlways("Time added: %f microseconds %s", (addedTimeEnd - addedTimeStart) * 1.0e6, resourceLoadInfo.resourceURL.string().utf8().data()); #endif return finalActions; }
Vector<Action> ContentExtensionsBackend::actionsForResourceLoad(const ResourceLoadInfo& resourceLoadInfo) const { #if CONTENT_EXTENSIONS_PERFORMANCE_REPORTING double addedTimeStart = monotonicallyIncreasingTime(); #endif if (resourceLoadInfo.resourceURL.protocolIsData()) return Vector<Action>(); const String& urlString = resourceLoadInfo.resourceURL.string(); ASSERT_WITH_MESSAGE(urlString.containsOnlyASCII(), "A decoded URL should only contain ASCII characters. The matching algorithm assumes the input is ASCII."); const CString& urlCString = urlString.utf8(); Vector<Action> finalActions; ResourceFlags flags = resourceLoadInfo.getResourceFlags(); for (auto& contentExtension : m_contentExtensions.values()) { RELEASE_ASSERT(contentExtension); const CompiledContentExtension& compiledExtension = contentExtension->compiledExtension(); DFABytecodeInterpreter interpreter(compiledExtension.bytecode(), compiledExtension.bytecodeLength(), contentExtension->m_pagesUsed); DFABytecodeInterpreter::Actions triggeredActions = interpreter.interpret(urlCString, flags); const SerializedActionByte* actions = compiledExtension.actions(); const unsigned actionsLength = compiledExtension.actionsLength(); bool sawIgnorePreviousRules = false; if (!triggeredActions.isEmpty()) { Vector<unsigned> actionLocations; actionLocations.reserveInitialCapacity(triggeredActions.size()); for (auto actionLocation : triggeredActions) actionLocations.append(static_cast<unsigned>(actionLocation)); std::sort(actionLocations.begin(), actionLocations.end()); // Add actions in reverse order to properly deal with IgnorePreviousRules. for (unsigned i = actionLocations.size(); i; i--) { Action action = Action::deserialize(actions, actionsLength, actionLocations[i - 1]); action.setExtensionIdentifier(contentExtension->identifier()); if (action.type() == ActionType::IgnorePreviousRules) { sawIgnorePreviousRules = true; break; } finalActions.append(action); } } if (!sawIgnorePreviousRules) { DFABytecodeInterpreter::Actions universalActions = interpreter.actionsFromDFARoot(); for (auto actionLocation : universalActions) { Action action = Action::deserialize(actions, actionsLength, static_cast<unsigned>(actionLocation)); action.setExtensionIdentifier(contentExtension->identifier()); // CSS selectors were already compiled into a stylesheet using globalDisplayNoneSelectors. if (action.type() != ActionType::CSSDisplayNoneSelector) finalActions.append(action); } finalActions.append(Action(ActionType::CSSDisplayNoneStyleSheet, contentExtension->identifier())); finalActions.last().setExtensionIdentifier(contentExtension->identifier()); } } #if CONTENT_EXTENSIONS_PERFORMANCE_REPORTING double addedTimeEnd = monotonicallyIncreasingTime(); WTFLogAlways("Time added: %f microseconds %s", (addedTimeEnd - addedTimeStart) * 1.0e6, resourceLoadInfo.resourceURL.string().utf8().data()); #endif return finalActions; }