From 1a9e09332261d18ee892fc3613f16a0e80d115e0 Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Sun, 21 May 2017 20:24:57 +0200 Subject: Reworking URL filter --- src/blocker/blockerrule.cpp | 170 +++----------------------------------------- 1 file changed, 11 insertions(+), 159 deletions(-) (limited to 'src/blocker/blockerrule.cpp') diff --git a/src/blocker/blockerrule.cpp b/src/blocker/blockerrule.cpp index b9c3730..ca4f339 100644 --- a/src/blocker/blockerrule.cpp +++ b/src/blocker/blockerrule.cpp @@ -20,72 +20,17 @@ #include "blockerrule.h" -/* AdBlock filter reference - * https://adblockplus.org/en/filters - * https://adblockplus.org/en/filter-cheatsheet - */ - -BlockerRule::BlockerRule(QString rule, QObject *parent) : +BlockerRule::BlockerRule(RegExp firstPartyUrl, RegExp requestUrl, NavigationType nav, ResourceType res, bool shouldBlock, QObject *parent) : QObject(parent) { - m_filter = rule; - QString pattern = rule; - - // Empty rule or comment - if(pattern.trimmed().isEmpty() || pattern.startsWith("!")) { - m_valid = false; - return; - } - - // Exception - if(pattern.startsWith("@@")) { - m_exception = true; - pattern.remove(0, 2); - } - - // Ignore element hiding rules for now - if(pattern.contains("##") || pattern.contains("#@#")) { - m_valid = false; - return; - } - - // Options - if(pattern.contains("$")) { - QString opts = pattern.mid(pattern.indexOf("$")+1); - pattern.remove(pattern.indexOf("$"), pattern.length()); - - const QStringList optList = opts.split(','); - QStringList::const_iterator i; - for(i = optList.constBegin(); i != optList.constEnd(); ++i) { - parseOption(*i); - } - } - - // Regular expression - if(rule.startsWith("/") && rule.endsWith("/")) { - m_valid = true; - ruleExpression.setPattern(pattern); - return; - } - - // Domain rules - if(pattern.startsWith("||")) { - pattern.remove(0, 2); - // find the end point for the domain - int end = pattern.indexOf(QRegularExpression("(?:[^\\w\\d\\_\\-\\.\\%]|$)"), 0); - domainExpression.setPattern(pattern.mid(0, end)); - pattern.remove(0, end+1); - } else if(pattern.startsWith("|") && pattern.endsWith("|")) { - pattern.remove(0, 1); - pattern.chop(1); - domainExpression.setPattern(pattern); - } else { - domainExpression.setPattern(".*"); - } + m_firstPartyUrl = firstPartyUrl; + m_requestUrl = requestUrl; + m_navRules = nav; + m_resRules = res; + m_shouldBlock = shouldBlock; - // Regular rule - ruleExpression.setWildcardPattern(pattern); m_valid = true; + } bool BlockerRule::match(const QWebEngineUrlRequestInfo &info) @@ -95,20 +40,11 @@ bool BlockerRule::match(const QWebEngineUrlRequestInfo &info) } // if both domain and rule match - if(domainExpression.match(info.requestUrl().host()) && ruleExpression.match(info.requestUrl().toString())) { - - // option explicitly allows - if(matchOptions(info, m_whitelistOptions)) { - return false; - } + if(m_firstPartyUrl.hasMatch(info.firstPartyUrl().toString()) && m_requestUrl.hasMatch(info.requestUrl().toString())) { - // option explicitly bans - if(matchOptions(info, m_blacklistOptions)) { - return true; - } + // TODO: check options - // no options, but both domain and rule match --> rule matches - return true; + return m_shouldBlock; } // domain and/or rule do not match @@ -119,92 +55,8 @@ bool BlockerRule::isValid() { return m_valid; } -bool BlockerRule::isException() -{ - return m_exception; -} QString BlockerRule::filter() const { - return m_filter; -} - -void BlockerRule::parseOption(const QString &opt) -{ - if(opt.startsWith("script")) { - m_blacklistOptions.setFlag(RuleOption::script, true); - } else if(opt.startsWith("~script")) { - m_whitelistOptions.setFlag(RuleOption::script, true); - - } else if(opt.startsWith("image")) { - m_blacklistOptions.setFlag(RuleOption::image, true); - } else if(opt.startsWith("~image")) { - m_whitelistOptions.setFlag(RuleOption::image, true); - - } else if(opt.startsWith("stylesheet")) { - m_blacklistOptions.setFlag(RuleOption::stylesheet, true); - } else if(opt.startsWith("~stylesheet")) { - m_whitelistOptions.setFlag(RuleOption::stylesheet, true); - - } else if(opt.startsWith("object")) { - m_blacklistOptions.setFlag(RuleOption::object, true); - } else if(opt.startsWith("~object")) { - m_whitelistOptions.setFlag(RuleOption::object, true); - - } else if(opt.startsWith("object-subrequest")) { - m_blacklistOptions.setFlag(RuleOption::objectsubrequest, true); - } else if(opt.startsWith("~object-subrequest")) { - m_whitelistOptions.setFlag(RuleOption::objectsubrequest, true); - - } else if(opt.startsWith("subdocument")) { - m_blacklistOptions.setFlag(RuleOption::subdocument, true); - } else if(opt.startsWith("~subdocument")) { - m_whitelistOptions.setFlag(RuleOption::subdocument, true); - } -} - -bool BlockerRule::matchOptions(const QWebEngineUrlRequestInfo &info, const RuleOptions &options) -{ - // no options are defined - if(options == 0) { - return false; - } - - bool hasOption = false; - switch (info.resourceType()) { - case QWebEngineUrlRequestInfo::ResourceTypeScript: - if(options.testFlag(RuleOption::script)) { - hasOption = true; - } - break; - case QWebEngineUrlRequestInfo::ResourceTypeImage: - if(options.testFlag(RuleOption::image)) { - hasOption = true; - } - break; - case QWebEngineUrlRequestInfo::ResourceTypeStylesheet: - if(options.testFlag(RuleOption::stylesheet)) { - hasOption = true; - } - break; - case QWebEngineUrlRequestInfo::ResourceTypeObject: - if(options.testFlag(RuleOption::object)) { - hasOption = true; - } - break; - case QWebEngineUrlRequestInfo::ResourceTypePluginResource: - if(options.testFlag(RuleOption::objectsubrequest)) { - hasOption = true; - } - break; - case QWebEngineUrlRequestInfo::ResourceTypeSubFrame: - if(options.testFlag(RuleOption::subdocument)) { - hasOption = true; - } - break; - default: - break; - } - - return hasOption; + return m_firstPartyUrl.pattern() + m_requestUrl.pattern(); } -- cgit v1.2.1