1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
/*
* This file is part of smolbote. It's copyrighted by the contributors recorded
* in the version control history of the file, available from its original
* location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote
*
* SPDX-License-Identifier: GPL-3.0
*/
#ifndef SMOLBOTE_ADBLOCKRULE_H
#define SMOLBOTE_ADBLOCKRULE_H
#include "../filterleaf.h"
#include <optional>
#include <QRegularExpression>
#include <QStringMatcher>
template <typename T>
class ContentsMatcher
{
public:
ContentsMatcher(const QString &pattern, FilterLeaf::UrlMatchType matchType)
{
this->matchType = matchType;
patternLength = pattern.length();
matcher.setPattern(pattern);
if constexpr(std::is_same_v<T, QRegularExpression>) {
matcher.setPatternOptions(matcher.patternOptions() | QRegularExpression::CaseInsensitiveOption);
} else if constexpr(std::is_same_v<T, QStringMatcher>) {
matcher.setCaseSensitivity(Qt::CaseInsensitive);
}
}
bool hasMatch(const QString &where) const
{
if constexpr(std::is_same_v<T, QStringMatcher>) {
switch (matchType) {
case FilterLeaf::InvalidMatch:
case FilterLeaf::RegularExpressionMatch:
case FilterLeaf::DomainMatch:
qWarning("ContentsMatcher is a String Matcher, but not doing string matching!");
return false;
case FilterLeaf::StringContains:
return (matcher.indexIn(where) != -1);
case FilterLeaf::StringStartsWith:
return (matcher.indexIn(where) == 0);
case FilterLeaf::StringEndsWith:
return (matcher.indexIn(where) == where.length() - patternLength);
case FilterLeaf::StringEquals:
return (matcher.indexIn(where) == 0) && (patternLength == where.length());
}
} else if constexpr(std::is_same_v<T, QRegularExpression>) {
if(matchType != FilterLeaf::RegularExpressionMatch)
qWarning("ContentsMatcher is a regular expression, but not doing a regular expression match!");
return matcher.match(where).hasMatch();
} else {
qWarning("Matcher has no backend, returning false");
return false;
}
}
private:
int patternLength;
T matcher;
FilterLeaf::UrlMatchType matchType;
};
class AdBlockRule : public FilterLeaf
{
public:
explicit AdBlockRule(FilterLeaf::UrlMatchType matchType, const QString &filter, FilterLeaf::Action action);
~AdBlockRule()
{
delete stringMatcher;
delete regExp;
};
void mergeOptions(const QHash<QWebEngineUrlRequestInfo::ResourceType, bool> &options);
bool match(const QUrl &requestUrl) const override;
bool match(const QUrl &requestUrl, QWebEngineUrlRequestInfo::ResourceType type) const;
std::pair<FilterLeaf::Action, QVariant> action() const override;
private:
/* Once C++20 comes out, perhaps this can be replaced with a concept template */
QStringMatcher *stringMatcher = nullptr;
QRegExp *regExp = nullptr;
};
#endif // SMOLBOTE_ADBLOCKRULE_H
|