diff options
Diffstat (limited to 'src/webengine')
-rw-r--r-- | src/webengine/blockerrule.cpp | 82 | ||||
-rw-r--r-- | src/webengine/blockerrule.h | 17 |
2 files changed, 91 insertions, 8 deletions
diff --git a/src/webengine/blockerrule.cpp b/src/webengine/blockerrule.cpp index 3a35ab6..3146854 100644 --- a/src/webengine/blockerrule.cpp +++ b/src/webengine/blockerrule.cpp @@ -20,20 +20,55 @@ #include "blockerrule.h" +/* AdBlock filter reference + * https://adblockplus.org/en/filters + * https://adblockplus.org/en/filter-cheatsheet + */ + BlockerRule::BlockerRule(QString rule, QObject *parent) : QObject(parent) { QString pattern = rule; - if(rule.startsWith("@@")) { + // Empty rule or comment + if(pattern.trimmed().isEmpty() || pattern.startsWith("!")) { + m_type = RuleType::Invalid; + return; + } + + // Exception + if(pattern.startsWith("@@")) { m_exception = true; pattern = pattern.remove(0, 2); - } else { - m_exception = false; } - ruleExpression.setPattern(pattern); - m_valid = true; + // Domain + if(pattern.startsWith("||")) { + m_type = RuleType::DomainMatch; + m_domain = pattern.mid(2, pattern.indexOf("^")-2); + return; + } + + // Regular expression + if(rule.startsWith("/") && rule.endsWith("/")) { + m_type = RuleType::RegularExpressionMatch; + ruleExpression.setPattern(pattern); + return; + } + + // Regular rule + ruleExpression.setPattern(fromWildcardMatch(pattern)); + m_type = RuleType::WildcardMatch; +} + +QString BlockerRule::pattern() const +{ + return ruleExpression.pattern(); +} + +QString BlockerRule::domain() const +{ + return m_domain; } bool BlockerRule::match(const QUrl &url) @@ -43,9 +78,44 @@ bool BlockerRule::match(const QUrl &url) bool BlockerRule::isValid() { - return m_valid; + if(m_type == RuleType::Invalid) { + return false; + } else { + return true; + } } bool BlockerRule::isException() { return m_exception; } + +QString BlockerRule::fromWildcardMatch(const QString &pattern) +{ + QString parsed; + + for(int i=0; i<pattern.length(); i++) { + const QChar c = pattern.at(i); + switch (c.toLatin1()) { + case '*': + parsed.append(".*"); + break; + case '^': + parsed.append("(?:[^\\w\\d\\_\\-\\.\\%]|$)"); + break; + case '|': + if(i == 0) { + // beginning of string + parsed.append('^'); + } else { + // end of string + parsed.append('$'); + } + break; + default: + parsed.append(c); + break; + } + } + + return parsed; +} diff --git a/src/webengine/blockerrule.h b/src/webengine/blockerrule.h index cf1dc19..95d82b7 100644 --- a/src/webengine/blockerrule.h +++ b/src/webengine/blockerrule.h @@ -29,8 +29,17 @@ class BlockerRule : public QObject { Q_OBJECT public: + enum RuleType { + Invalid, + DomainMatch, + RegularExpressionMatch, + WildcardMatch + }; + explicit BlockerRule(QString rule, QObject *parent = 0); + QString pattern() const; + QString domain() const; bool match(const QUrl &url); bool isValid(); bool isException(); @@ -40,8 +49,12 @@ signals: public slots: private: - bool m_valid; - bool m_exception; + // TODO: subclass QRegularExpression and move this there + QString fromWildcardMatch(const QString &pattern); + + RuleType m_type; + bool m_exception = false; + QString m_domain; QRegularExpression ruleExpression; }; |