aboutsummaryrefslogtreecommitdiff
path: root/lib/urlfilter/formats/adblocklist.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/urlfilter/formats/adblocklist.cpp')
-rw-r--r--lib/urlfilter/formats/adblocklist.cpp95
1 files changed, 95 insertions, 0 deletions
diff --git a/lib/urlfilter/formats/adblocklist.cpp b/lib/urlfilter/formats/adblocklist.cpp
new file mode 100644
index 0000000..772c252
--- /dev/null
+++ b/lib/urlfilter/formats/adblocklist.cpp
@@ -0,0 +1,95 @@
+#include "adblocklist.h"
+
+AdBlockList::AdBlockList()
+{
+}
+
+QString AdBlockList::metadata(const QString &key) const
+{
+ return m_metadata.value(key, QString());
+}
+
+FilterLeaf::Action AdBlockList::match(const QUrl &firstParty, const QUrl &requestUrl, QWebEngineUrlRequestInfo::ResourceType type) const
+{
+ const QString request = requestUrl.toString();
+
+ for(auto &filter : m_rules) {
+ if(filter.matcher->hasMatch(request))
+ return filter.action;
+ }
+ return FilterLeaf::NotMatched;
+}
+
+bool AdBlockList::parseLine(const QString &line)
+{
+ // remove whitespace from start/end of the line
+ QString parsedLine = line.trimmed();
+
+ // check if the line is empty
+ if(parsedLine.isEmpty())
+ return false;
+
+ // parse comment
+ if(parsedLine.startsWith(QLatin1Literal("!")))
+ return parseComment(parsedLine);
+
+ Filter filter;
+
+ // exception rules
+ if(parsedLine.startsWith(QLatin1Literal("@@"))) {
+ filter.action = FilterLeaf::Allow;
+ parsedLine.remove(0, 2);
+ }
+
+ // remove '*' at the beginning and the end
+ if(parsedLine.startsWith(QLatin1Literal("*")))
+ parsedLine = parsedLine.mid(1);
+ if(parsedLine.endsWith(QLatin1Literal("*")))
+ parsedLine.chop(1);
+
+ if(parsedLine.startsWith(QLatin1Literal("/")) && parsedLine.endsWith(QLatin1Literal("/"))) {
+ // regular expression rule
+ parsedLine = parsedLine.mid(1, parsedLine.length() - 2);
+ filter.matcher = new ContentsMatcher<QRegularExpression>(parsedLine, FilterLeaf::RegularExpressionMatch);
+
+ } else if(parsedLine.contains(QLatin1Literal("*"))) {
+ parsedLine = QRegularExpression::wildcardToRegularExpression(parsedLine);
+ filter.matcher = new ContentsMatcher<QRegularExpression>(parsedLine, FilterLeaf::RegularExpressionMatch);
+
+ } else if(parsedLine.startsWith(QLatin1Literal("||")) && parsedLine.endsWith(QLatin1Literal("^"))) {
+// matchType = FilterLeaf::DomainMatch;
+ parsedLine = parsedLine.mid(2, parsedLine.length() - 3);
+ filter.matcher = new ContentsMatcher<QString>(parsedLine, FilterLeaf::DomainMatch);
+
+ } else if(parsedLine.startsWith(QLatin1Literal("|")) && parsedLine.endsWith(QLatin1Literal("|"))) {
+ // string equals rule
+ parsedLine = parsedLine.mid(1, parsedLine.length() - 2);
+ filter.matcher = new ContentsMatcher<QStringMatcher>(parsedLine, FilterLeaf::StringEquals);
+
+ } else if(parsedLine.startsWith(QLatin1Literal("||"))) {
+ // string starts with rule
+ parsedLine = parsedLine.mid(2);
+ filter.matcher = new ContentsMatcher<QStringMatcher>(parsedLine, FilterLeaf::StringStartsWith);
+
+ } else if(parsedLine.endsWith(QLatin1Literal("|"))) {
+ // string ends with rule
+ parsedLine.chop(1);
+ filter.matcher = new ContentsMatcher<QStringMatcher>(parsedLine, FilterLeaf::StringEndsWith);
+
+ } else {
+ // generic contains rule
+ filter.matcher = new ContentsMatcher<QStringMatcher>(parsedLine, FilterLeaf::StringContains);
+ }
+
+
+ Q_CHECK_PTR(filter.matcher);
+ m_rules.emplace_back(std::move(filter));
+ return true;
+}
+
+bool AdBlockList::parseComment(const QString &commentLine)
+{
+ const QStringList comment = commentLine.mid(1).split(QLatin1Literal(": "));
+ m_metadata[comment.at(0).trimmed()] = comment.at(1).trimmed();
+ return true;
+}