File indexing completed on 2024-05-12 04:57:50
0001 /* ============================================================ 0002 * Falkon - Qt web browser 0003 * Copyright (C) 2013-2017 David Rosca <nowrep@gmail.com> 0004 * 0005 * This program is free software: you can redistribute it and/or modify 0006 * it under the terms of the GNU General Public License as published by 0007 * the Free Software Foundation, either version 3 of the License, or 0008 * (at your option) any later version. 0009 * 0010 * This program is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 * GNU General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU General Public License 0016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0017 * ============================================================ */ 0018 #include "adblocksearchtree.h" 0019 #include "adblockrule.h" 0020 0021 #include <QWebEngineUrlRequestInfo> 0022 0023 AdBlockSearchTree::AdBlockSearchTree() 0024 : m_root(new Node) 0025 { 0026 } 0027 0028 AdBlockSearchTree::~AdBlockSearchTree() 0029 { 0030 deleteNode(m_root); 0031 } 0032 0033 void AdBlockSearchTree::clear() 0034 { 0035 deleteNode(m_root); 0036 m_root = new Node; 0037 } 0038 0039 bool AdBlockSearchTree::add(const AdBlockRule* rule) 0040 { 0041 if (rule->m_type != AdBlockRule::StringContainsMatchRule) { 0042 return false; 0043 } 0044 0045 const QString filter = rule->m_matchString; 0046 int len = filter.size(); 0047 0048 if (len <= 0) { 0049 qDebug() << "AdBlockSearchTree: Inserting rule with filter len <= 0!" << rule->filter(); 0050 return false; 0051 } 0052 0053 Node* node = m_root; 0054 0055 for (int i = 0; i < len; ++i) { 0056 const QChar c = filter.at(i); 0057 Node *next = node->children.value(c); 0058 if (!next) { 0059 next = new Node; 0060 next->c = c; 0061 node->children[c] = next; 0062 } 0063 node = next; 0064 } 0065 0066 node->rule = rule; 0067 0068 return true; 0069 } 0070 0071 const AdBlockRule* AdBlockSearchTree::find(const QWebEngineUrlRequestInfo &request, const QString &domain, const QString &urlString) const 0072 { 0073 int len = urlString.size(); 0074 0075 if (len <= 0) { 0076 return nullptr; 0077 } 0078 0079 const QChar* string = urlString.constData(); 0080 0081 for (int i = 0; i < len; ++i) { 0082 const AdBlockRule* rule = prefixSearch(request, domain, urlString, string++, len - i); 0083 if (rule) { 0084 return rule; 0085 } 0086 } 0087 0088 return nullptr; 0089 } 0090 0091 const AdBlockRule* AdBlockSearchTree::prefixSearch(const QWebEngineUrlRequestInfo &request, const QString &domain, const QString &urlString, const QChar* string, int len) const 0092 { 0093 if (len <= 0) { 0094 return nullptr; 0095 } 0096 0097 QChar c = string[0]; 0098 0099 Node* node = m_root->children.value(c); 0100 if (!node) { 0101 return nullptr; 0102 } 0103 0104 for (int i = 1; i < len; ++i) { 0105 const QChar c = (++string)[0]; 0106 0107 if (node->rule && node->rule->networkMatch(request, domain, urlString)) { 0108 return node->rule; 0109 } 0110 0111 node = node->children.value(c); 0112 if (!node) { 0113 return nullptr; 0114 } 0115 } 0116 0117 if (node->rule && node->rule->networkMatch(request, domain, urlString)) { 0118 return node->rule; 0119 } 0120 0121 return nullptr; 0122 } 0123 0124 void AdBlockSearchTree::deleteNode(AdBlockSearchTree::Node* node) 0125 { 0126 if (!node) { 0127 return; 0128 } 0129 0130 QHashIterator<QChar, Node*> i(node->children); 0131 while (i.hasNext()) { 0132 i.next(); 0133 deleteNode(i.value()); 0134 } 0135 0136 delete node; 0137 }