LEFT | RIGHT |
1 /* | 1 /* |
2 * This file is part of Adblock Plus <https://adblockplus.org/>, | 2 * This file is part of Adblock Plus <https://adblockplus.org/>, |
3 * Copyright (C) 2006-2015 Eyeo GmbH | 3 * Copyright (C) 2006-2016 Eyeo GmbH |
4 * | 4 * |
5 * Adblock Plus is free software: you can redistribute it and/or modify | 5 * Adblock Plus is free software: you can redistribute it and/or modify |
6 * it under the terms of the GNU General Public License version 3 as | 6 * it under the terms of the GNU General Public License version 3 as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
8 * | 8 * |
9 * Adblock Plus is distributed in the hope that it will be useful, | 9 * Adblock Plus is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 * GNU General Public License for more details. | 12 * GNU General Public License for more details. |
13 * | 13 * |
14 * You should have received a copy of the GNU General Public License | 14 * You should have received a copy of the GNU General Public License |
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. | 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
16 */ | 16 */ |
17 | 17 |
18 #include "PluginStdAfx.h" | 18 #include "PluginStdAfx.h" |
19 #include "AdblockPlusClient.h" | 19 #include "AdblockPlusClient.h" |
20 #include "PluginFilter.h" | 20 #include "PluginFilter.h" |
21 #include "PluginSettings.h" | 21 #include "PluginSettings.h" |
22 #include "PluginMutex.h" | 22 #include "PluginMutex.h" |
23 #include "PluginSettings.h" | 23 #include "PluginSettings.h" |
24 #include "PluginSystem.h" | 24 #include "PluginSystem.h" |
25 #include "PluginClass.h" | 25 #include "PluginClass.h" |
| 26 #include "PluginUtil.h" |
26 #include "mlang.h" | 27 #include "mlang.h" |
27 #include "TokenSequence.h" | |
28 #include "..\shared\CriticalSection.h" | 28 #include "..\shared\CriticalSection.h" |
29 #include "..\shared\Utils.h" | 29 #include "..\shared\Utils.h" |
30 #include "..\shared\MsHTMLUtils.h" | 30 #include "..\shared\MsHTMLUtils.h" |
31 | 31 |
32 // The filters are described at http://adblockplus.org/en/filters | 32 // The filters are described at http://adblockplus.org/en/filters |
33 | 33 |
34 static CriticalSection s_criticalSectionFilterMap; | 34 static CriticalSection s_criticalSectionFilterMap; |
35 | 35 |
36 std::wstring ToLowerString(const std::wstring& s) | |
37 { | |
38 return ToWstring(ToCString(s).MakeLower()); | |
39 } | |
40 | |
41 // ============================================================================ | 36 // ============================================================================ |
42 // CFilterElementHide | 37 // CFilterElementHide |
43 // ============================================================================ | 38 // ============================================================================ |
44 void ElementHideParseError(const std::wstring& filterText, const std::string& re
ason) | 39 namespace |
45 { | 40 { |
46 std::string message( | 41 class ElementHideParseException |
47 "CFilterElementHide::CFilterElementHide, error parsing selector \"" | 42 : public std::runtime_error |
48 + ToUtf8String(filterText) + "\" (" + reason + ")" | 43 { |
49 ); | 44 std::string message(const std::wstring& filterText, const std::string& reaso
n) |
50 DEBUG_FILTER(ToUtf16String(message)); | 45 { |
51 throw std::runtime_error(message); | 46 std::string s( |
| 47 "CFilterElementHide::CFilterElementHide, error parsing selector \"" |
| 48 + ToUtf8String(filterText) + "\" (" + reason + ")" |
| 49 ); |
| 50 DEBUG_FILTER(ToUtf16String(s)); |
| 51 return s; |
| 52 } |
| 53 public: |
| 54 ElementHideParseException(const std::wstring& filterText, const std::string&
reason) |
| 55 : std::runtime_error(message(filterText, reason)) |
| 56 {} |
| 57 }; |
52 } | 58 } |
53 | 59 |
54 CFilterElementHide::CFilterElementHide(const std::wstring& filterText) | 60 CFilterElementHide::CFilterElementHide(const std::wstring& filterText) |
55 : m_filterText(filterText), m_type(ETraverserComplexType::TRAVERSER_TYPE_ERROR
) | 61 : m_filterText(filterText), m_type(ETraverserComplexType::TRAVERSER_TYPE_ERROR
) |
56 { | 62 { |
57 std::wstring filterSuffix(filterText); // The unparsed remainder of the input
filter text | 63 std::wstring filterSuffix(filterText); // The unparsed remainder of the input
filter text |
58 | 64 |
59 // Find tag name, class or any (*) | 65 // Find tag name, class or any (*) |
60 wchar_t firstTag = filterText[0]; | 66 wchar_t firstTag = filterText[0]; |
61 if (firstTag == '*') | 67 if (firstTag == '*') |
62 { | 68 { |
63 // Any tag | 69 // Any tag |
64 filterSuffix = filterSuffix.substr(1); | 70 filterSuffix = filterSuffix.substr(1); |
65 } | 71 } |
66 else if (firstTag == '[' || firstTag == '.' || firstTag == '#') | 72 else if (firstTag == '[' || firstTag == '.' || firstTag == '#') |
67 { | 73 { |
68 // Any tag (implicitly) | 74 // Any tag (implicitly) |
69 } | 75 } |
70 else if (isalnum(firstTag)) | 76 else if (isalnum(firstTag)) |
71 { | 77 { |
72 // Real tag | 78 // Real tag |
73 //TODO: Add support for descendant selectors | 79 // TODO: Add support for descendant selectors |
74 auto pos = filterSuffix.find_first_of(L".#[("); | 80 auto pos = filterSuffix.find_first_of(L".#[("); |
75 if (pos == std::wstring::npos) | 81 if (pos == std::wstring::npos) |
76 { | 82 { |
77 pos = filterSuffix.length(); | 83 pos = filterSuffix.length(); |
78 } | 84 } |
79 m_tag = ToLowerString(filterSuffix.substr(0,pos)); | 85 m_tag = ToLowerString(filterSuffix.substr(0, pos)); |
80 filterSuffix = filterSuffix.substr(pos); | 86 filterSuffix = filterSuffix.substr(pos); |
81 } | 87 } |
82 else | 88 else |
83 { | 89 { |
84 // Error | 90 // Error |
85 ElementHideParseError(filterText, "invalid tag"); | 91 throw ElementHideParseException(filterText, "invalid tag"); |
86 } | 92 } |
87 | 93 |
88 // Find Id and class name | 94 // Find Id and class name |
89 if (!filterSuffix.empty()) | 95 if (!filterSuffix.empty()) |
90 { | 96 { |
91 wchar_t firstId = filterSuffix[0]; | 97 wchar_t firstId = filterSuffix[0]; |
92 | 98 |
93 // Id | 99 // Id |
94 if (firstId == '#') | 100 if (firstId == '#') |
95 { | 101 { |
96 auto pos = filterSuffix.find('['); | 102 auto pos = filterSuffix.find('['); |
97 if (pos == std::wstring::npos) | 103 if (pos == std::wstring::npos) |
98 { | 104 { |
99 pos = filterSuffix.length(); | 105 pos = filterSuffix.length(); |
100 } | 106 } |
101 m_tagId = filterSuffix.substr(1, pos - 1); | 107 m_tagId = filterSuffix.substr(1, pos - 1); |
102 filterSuffix = filterSuffix.substr(pos); | 108 filterSuffix = filterSuffix.substr(pos); |
103 pos = m_tagId.find(L"."); | 109 pos = m_tagId.find(L"."); |
104 if (pos != std::wstring::npos) | 110 if (pos != std::wstring::npos) |
105 { | 111 { |
106 if (pos == 0) | 112 if (pos == 0) |
107 { | 113 { |
108 ElementHideParseError(filterText, "empty tag id"); | 114 throw ElementHideParseException(filterText, "empty tag id"); |
109 } | 115 } |
110 m_tagClassName = m_tagId.substr(pos + 1); | 116 m_tagClassName = m_tagId.substr(pos + 1); |
111 m_tagId = m_tagId.substr(0, pos); | 117 m_tagId = m_tagId.substr(0, pos); |
112 } | 118 } |
113 } | 119 } |
114 // Class name | 120 // Class name |
115 else if (firstId == '.') | 121 else if (firstId == '.') |
116 { | 122 { |
117 auto pos = filterSuffix.find('['); | 123 auto pos = filterSuffix.find('['); |
118 if (pos == std::wstring::npos) | 124 if (pos == std::wstring::npos) |
119 { | 125 { |
120 pos = filterSuffix.length(); | 126 pos = filterSuffix.length(); |
121 } | 127 } |
122 m_tagClassName = filterSuffix.substr(1, pos - 1); | 128 m_tagClassName = filterSuffix.substr(1, pos - 1); |
123 filterSuffix = filterSuffix.substr(pos); | 129 filterSuffix = filterSuffix.substr(pos); |
124 } | 130 } |
125 } | 131 } |
126 | 132 |
127 while (!filterSuffix.empty()) | 133 while (!filterSuffix.empty()) |
128 { | 134 { |
129 if (filterSuffix[0] != '[') | 135 if (filterSuffix[0] != '[') |
130 { | 136 { |
131 ElementHideParseError(filterText, "expected '['"); | 137 throw ElementHideParseException(filterText, "expected '['"); |
132 } | 138 } |
133 auto endPos = filterSuffix.find(']') ; | 139 auto endPos = filterSuffix.find(']') ; |
134 if (endPos == std::wstring::npos) | 140 if (endPos == std::wstring::npos) |
135 { | 141 { |
136 ElementHideParseError(filterText, "expected ']'"); | 142 throw ElementHideParseException(filterText, "expected ']'"); |
137 } | 143 } |
138 std::wstring arg = filterSuffix.substr(1, endPos - 1); | 144 std::wstring arg = filterSuffix.substr(1, endPos - 1); |
139 filterSuffix = filterSuffix.substr(endPos + 1); | 145 filterSuffix = filterSuffix.substr(endPos + 1); |
140 | 146 |
141 CFilterElementHideAttrSelector attrSelector; | 147 CFilterElementHideAttrSelector attrSelector; |
142 auto posEquals = arg.find('='); | 148 auto posEquals = arg.find('='); |
143 if (posEquals != std::wstring::npos) | 149 if (posEquals != std::wstring::npos) |
144 { | 150 { |
145 if (posEquals == 0) | 151 if (posEquals == 0) |
146 { | 152 { |
147 ElementHideParseError(filterText, "empty attribute name before '='"); | 153 throw ElementHideParseException(filterText, "empty attribute name before
'='"); |
148 } | 154 } |
149 attrSelector.m_value = arg.substr(posEquals + 1); | 155 attrSelector.m_value = arg.substr(posEquals + 1); |
150 if (attrSelector.m_value.length() >= 2 && attrSelector.m_value[0] == '\"'
&& attrSelector.m_value[attrSelector.m_value.length() - 1] == '\"') | 156 if (attrSelector.m_value.length() >= 2 && attrSelector.m_value[0] == '\"'
&& attrSelector.m_value[attrSelector.m_value.length() - 1] == '\"') |
151 { | 157 { |
152 attrSelector.m_value = attrSelector.m_value.substr(1, attrSelector.m_val
ue.length() - 2); | 158 attrSelector.m_value = attrSelector.m_value.substr(1, attrSelector.m_val
ue.length() - 2); |
153 } | 159 } |
154 | 160 |
155 if (arg[posEquals - 1] == '^') | 161 if (arg[posEquals - 1] == '^') |
156 { | 162 { |
157 attrSelector.m_pos = CFilterElementHideAttrPos::STARTING; | 163 attrSelector.m_pos = CFilterElementHideAttrPos::STARTING; |
158 } | 164 } |
159 else if (arg[posEquals - 1] == '*') | 165 else if (arg[posEquals - 1] == '*') |
160 { | 166 { |
161 attrSelector.m_pos = CFilterElementHideAttrPos::ANYWHERE; | 167 attrSelector.m_pos = CFilterElementHideAttrPos::ANYWHERE; |
162 } | 168 } |
163 else if (arg[posEquals - 1] == '$') | 169 else if (arg[posEquals - 1] == '$') |
164 { | 170 { |
165 attrSelector.m_pos = CFilterElementHideAttrPos::ENDING; | 171 attrSelector.m_pos = CFilterElementHideAttrPos::ENDING; |
166 } | 172 } |
167 if (attrSelector.m_pos != CFilterElementHideAttrPos::POS_NONE) | 173 if (attrSelector.m_pos != CFilterElementHideAttrPos::POS_NONE) |
168 { | 174 { |
169 if (posEquals == 1) | 175 if (posEquals == 1) |
170 { | 176 { |
171 ElementHideParseError(filterText, "empty attribute name before " + std
::string(1, static_cast<char>(arg[0])) + "'='"); | 177 throw ElementHideParseException(filterText, "empty attribute name befo
re " + std::string(1, static_cast<char>(arg[0])) + "'='"); |
172 } | 178 } |
173 attrSelector.m_attr = arg.substr(0, posEquals - 1); | 179 attrSelector.m_attr = arg.substr(0, posEquals - 1); |
174 } | 180 } |
175 else | 181 else |
176 { | 182 { |
177 attrSelector.m_pos = CFilterElementHideAttrPos::EXACT; | 183 attrSelector.m_pos = CFilterElementHideAttrPos::EXACT; |
178 attrSelector.m_attr = arg.substr(0, posEquals); | 184 attrSelector.m_attr = arg.substr(0, posEquals); |
179 } | 185 } |
180 } | 186 } |
181 | 187 |
182 if (attrSelector.m_attr == L"style") | 188 if (attrSelector.m_attr == L"style") |
183 { | 189 { |
184 attrSelector.m_type = CFilterElementHideAttrType::STYLE; | 190 attrSelector.m_type = CFilterElementHideAttrType::STYLE; |
185 attrSelector.m_value = ToLowerString(attrSelector.m_value); | 191 attrSelector.m_value = ToLowerString(attrSelector.m_value); |
186 } | 192 } |
187 else if (attrSelector.m_attr == L"id") | 193 else if (attrSelector.m_attr == L"id") |
188 { | 194 { |
189 attrSelector.m_type = CFilterElementHideAttrType::ID; | 195 attrSelector.m_type = CFilterElementHideAttrType::ID; |
190 } | 196 } |
191 else if (attrSelector.m_attr == L"class") | 197 else if (attrSelector.m_attr == L"class") |
192 { | 198 { |
193 attrSelector.m_type = CFilterElementHideAttrType::CLASS; | 199 attrSelector.m_type = CFilterElementHideAttrType::CLASS; |
194 } | 200 } |
195 m_attributeSelectors.push_back(attrSelector); | 201 m_attributeSelectors.push_back(attrSelector); |
196 } | 202 } |
197 | 203 |
198 // End check | 204 // End check |
199 if (!filterSuffix.empty()) | 205 if (!filterSuffix.empty()) |
200 { | 206 { |
201 ElementHideParseError(filterText, "extra characters at end"); | 207 throw ElementHideParseException(filterText, "extra characters at end"); |
202 } | 208 } |
203 } | 209 } |
204 | 210 |
205 CFilterElementHide::CFilterElementHide(const CFilterElementHide& filter) | 211 CFilterElementHide::CFilterElementHide(const CFilterElementHide& filter) |
206 { | 212 { |
207 m_filterText = filter.m_filterText; | 213 m_filterText = filter.m_filterText; |
208 | 214 |
209 m_tagId = filter.m_tagId; | 215 m_tagId = filter.m_tagId; |
210 m_tagClassName = filter.m_tagClassName; | 216 m_tagClassName = filter.m_tagClassName; |
211 | 217 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 | 251 |
246 bool CFilterElementHide::IsMatchFilterElementHide(IHTMLElement* pEl) const | 252 bool CFilterElementHide::IsMatchFilterElementHide(IHTMLElement* pEl) const |
247 { | 253 { |
248 HRESULT hr; | 254 HRESULT hr; |
249 /* | 255 /* |
250 * If a tag id is specified, it must match | 256 * If a tag id is specified, it must match |
251 */ | 257 */ |
252 if (!m_tagId.empty()) | 258 if (!m_tagId.empty()) |
253 { | 259 { |
254 CComBSTR idBstr; | 260 CComBSTR idBstr; |
255 if (FAILED( pEl->get_id(&idBstr)) || !idBstr || m_tagId != ToWstring(idBstr)
) | 261 if (FAILED(pEl->get_id(&idBstr)) || !idBstr || m_tagId != ToWstring(idBstr)) |
256 { | 262 { |
257 return false; | 263 return false; |
258 } | 264 } |
259 } | 265 } |
260 /* | 266 /* |
261 * If a class name is specified, it must match | 267 * If a class name is specified, it must match |
262 */ | 268 */ |
263 if (!m_tagClassName.empty()) | 269 if (!m_tagClassName.empty()) |
264 { | 270 { |
265 CComBSTR classNameListBstr; | 271 CComBSTR classNameListBstr; |
266 hr = pEl->get_className(&classNameListBstr); | 272 hr = pEl->get_className(&classNameListBstr); |
267 if (FAILED(hr) || !classNameListBstr) | 273 if (FAILED(hr) || !classNameListBstr) |
268 { | 274 { |
269 return false; // We can't match a class name if there's no class name | 275 return false; // We can't match a class name if there's no class name |
270 } | 276 } |
271 std::wstring classNameList(ToWstring(classNameListBstr)); | 277 std::wstring classNameList(ToWstring(classNameListBstr)); |
272 if (classNameList.empty()) | 278 if (classNameList.empty()) |
273 { | 279 { |
274 return false; | 280 return false; |
275 } | 281 } |
276 // TODO: Consider case of multiple classes. (m_tagClassName can be something
like "foo.bar") | 282 // TODO: Consider case of multiple classes. (m_tagClassName can be something
like "foo.bar") |
277 /* | 283 /* |
278 * Match when 'm_tagClassName' appears as a token within classNameList | 284 * Match when 'm_tagClassName' appears as a token within classNameList |
279 */ | 285 */ |
280 bool foundMatch = false; | 286 bool foundMatch = false; |
281 TokenSequence<std::wstring> ts(classNameList, L" "); | 287 wchar_t* nextToken = nullptr; |
282 for (auto iterClassName = ts.cbegin(); iterClassName != ts.cend(); ++iterCla
ssName) | 288 const wchar_t* token = wcstok_s(&classNameList[0], L" ", &nextToken); |
283 { | 289 while (token != nullptr) |
284 if (*iterClassName == m_tagClassName) | 290 { |
| 291 if (std::wstring(token) == m_tagClassName) |
285 { | 292 { |
286 foundMatch = true; | 293 foundMatch = true; |
287 break; | 294 break; |
288 } | 295 } |
| 296 token = wcstok_s(nullptr, L" ", &nextToken); |
289 } | 297 } |
290 if (!foundMatch) | 298 if (!foundMatch) |
291 { | 299 { |
292 return false; | 300 return false; |
293 } | 301 } |
294 } | 302 } |
295 /* | 303 /* |
296 * If a tag name is specified, it must match | 304 * If a tag name is specified, it must match |
297 */ | 305 */ |
298 if (!m_tag.empty()) | 306 if (!m_tag.empty()) |
299 { | 307 { |
300 CComBSTR tagNameBstr; | 308 CComBSTR tagNameBstr; |
301 if (FAILED(pEl->get_tagName(&tagNameBstr)) || !tagNameBstr) | 309 if (FAILED(pEl->get_tagName(&tagNameBstr)) || !tagNameBstr) |
302 { | 310 { |
303 return false; | 311 return false; |
304 } | 312 } |
305 if (m_tag != ToLowerString(ToWstring(tagNameBstr))) | 313 if (m_tag != ToLowerString(ToWstring(tagNameBstr))) |
306 { | 314 { |
307 return false; | 315 return false; |
308 } | 316 } |
309 } | 317 } |
310 /* | 318 /* |
311 * Match each attribute | 319 * Match each attribute |
312 */ | 320 */ |
313 for (auto attrIt = m_attributeSelectors.begin(); attrIt != m_attributeSelector
s.end(); ++ attrIt) | 321 for (auto attrIt = m_attributeSelectors.begin(); attrIt != m_attributeSelector
s.end(); ++attrIt) |
314 { | 322 { |
315 std::wstring value; | 323 std::wstring value; |
316 bool attrFound = false; | 324 bool attrFound = false; |
317 if (attrIt->m_type == CFilterElementHideAttrType::STYLE) | 325 if (attrIt->m_type == CFilterElementHideAttrType::STYLE) |
318 { | 326 { |
319 CComPtr<IHTMLStyle> pStyle; | 327 CComPtr<IHTMLStyle> pStyle; |
320 if (SUCCEEDED(pEl->get_style(&pStyle)) && pStyle) | 328 if (SUCCEEDED(pEl->get_style(&pStyle)) && pStyle) |
321 { | 329 { |
322 CComBSTR styleBstr; | 330 CComBSTR styleBstr; |
323 if (SUCCEEDED(pStyle->get_cssText(&styleBstr)) && styleBstr) | 331 if (SUCCEEDED(pStyle->get_cssText(&styleBstr)) && styleBstr) |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 | 510 |
503 return true; | 511 return true; |
504 } | 512 } |
505 | 513 |
506 bool CPluginFilter::IsElementHidden(const std::wstring& tag, IHTMLElement* pEl,
const std::wstring& domain, const std::wstring& indent) const | 514 bool CPluginFilter::IsElementHidden(const std::wstring& tag, IHTMLElement* pEl,
const std::wstring& domain, const std::wstring& indent) const |
507 { | 515 { |
508 std::wstring id; | 516 std::wstring id; |
509 CComBSTR idBstr; | 517 CComBSTR idBstr; |
510 if (SUCCEEDED(pEl->get_id(&idBstr)) && idBstr) | 518 if (SUCCEEDED(pEl->get_id(&idBstr)) && idBstr) |
511 { | 519 { |
512 id = std::wstring(ToWstring(idBstr)); | 520 id = ToWstring(idBstr); |
513 } | 521 } |
514 std::wstring classNames; | 522 std::wstring classNames; |
515 CComBSTR classNamesBstr; | 523 CComBSTR classNamesBstr; |
516 if (SUCCEEDED(pEl->get_className(&classNamesBstr)) && classNamesBstr) | 524 if (SUCCEEDED(pEl->get_className(&classNamesBstr)) && classNamesBstr) |
517 { | 525 { |
518 classNames = ToWstring(classNamesBstr); | 526 classNames = ToWstring(classNamesBstr); |
519 } | 527 } |
520 | 528 |
521 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 529 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); |
522 { | 530 { |
523 // Search tag/id filters | 531 // Search tag/id filters |
524 if (!id.empty()) | 532 if (!id.empty()) |
525 { | 533 { |
526 auto idItEnum = m_elementHideTagsId.equal_range(std::make_pair(tag, id)); | 534 auto idItEnum = m_elementHideTagsId.equal_range(std::make_pair(tag, id)); |
527 for (auto idIt = idItEnum.first; idIt != idItEnum.second; idIt ++) | 535 for (auto idIt = idItEnum.first; idIt != idItEnum.second; ++idIt) |
528 { | 536 { |
529 if (idIt->second.IsMatchFilterElementHide(pEl)) | 537 if (idIt->second.IsMatchFilterElementHide(pEl)) |
530 { | 538 { |
531 #ifdef ENABLE_DEBUG_RESULT | 539 #ifdef ENABLE_DEBUG_RESULT |
532 DEBUG_HIDE_EL(indent + L"HideEl::Found (tag/id) filter:" + idIt->secon
d.m_filterText); | 540 DEBUG_HIDE_EL(indent + L"HideEl::Found (tag/id) filter:" + idIt->secon
d.m_filterText); |
533 CPluginDebug::DebugResultHiding(tag, L"id:" + id, idIt->second.m_filte
rText); | 541 CPluginDebug::DebugResultHiding(tag, L"id:" + id, idIt->second.m_filte
rText); |
534 #endif | 542 #endif |
535 return true; | 543 return true; |
536 } | 544 } |
537 } | 545 } |
538 | 546 |
539 // Search general id | 547 // Search general id |
540 idItEnum = m_elementHideTagsId.equal_range(std::make_pair(L"", id)); | 548 idItEnum = m_elementHideTagsId.equal_range(std::make_pair(L"", id)); |
541 for (auto idIt = idItEnum.first; idIt != idItEnum.second; idIt ++) | 549 for (auto idIt = idItEnum.first; idIt != idItEnum.second; ++idIt) |
542 { | 550 { |
543 if (idIt->second.IsMatchFilterElementHide(pEl)) | 551 if (idIt->second.IsMatchFilterElementHide(pEl)) |
544 { | 552 { |
545 #ifdef ENABLE_DEBUG_RESULT | 553 #ifdef ENABLE_DEBUG_RESULT |
546 DEBUG_HIDE_EL(indent + L"HideEl::Found (?/id) filter:" + idIt->second.
m_filterText); | 554 DEBUG_HIDE_EL(indent + L"HideEl::Found (?/id) filter:" + idIt->second.
m_filterText); |
547 CPluginDebug::DebugResultHiding(tag, L"id:" + id, idIt->second.m_filte
rText); | 555 CPluginDebug::DebugResultHiding(tag, L"id:" + id, idIt->second.m_filte
rText); |
548 #endif | 556 #endif |
549 return true; | 557 return true; |
550 } | 558 } |
551 } | 559 } |
552 } | 560 } |
553 | 561 |
554 // Search tag/className filters | 562 // Search tag/className filters |
555 if (!classNames.empty()) | 563 if (!classNames.empty()) |
556 { | 564 { |
557 TokenSequence<std::wstring> ts(classNames, L" \t\n\r"); | 565 wchar_t* nextToken = nullptr; |
558 for (auto iterClassName = ts.cbegin(); iterClassName != ts.cend(); ++iterC
lassName) | 566 const wchar_t* token = wcstok_s(&classNames[0], L" \t\n\r", &nextToken); |
559 { | 567 while (token != nullptr) |
560 std::wstring className = *iterClassName; | 568 { |
| 569 std::wstring className(token); |
561 auto classItEnum = m_elementHideTagsClass.equal_range(std::make_pair(tag
, className)); | 570 auto classItEnum = m_elementHideTagsClass.equal_range(std::make_pair(tag
, className)); |
562 for (auto classIt = classItEnum.first; classIt != classItEnum.second; ++
classIt) | 571 for (auto classIt = classItEnum.first; classIt != classItEnum.second; ++
classIt) |
563 { | 572 { |
564 if (classIt->second.IsMatchFilterElementHide(pEl)) | 573 if (classIt->second.IsMatchFilterElementHide(pEl)) |
565 { | 574 { |
566 #ifdef ENABLE_DEBUG_RESULT | 575 #ifdef ENABLE_DEBUG_RESULT |
567 DEBUG_HIDE_EL(indent + L"HideEl::Found (tag/class) filter:" + classI
t->second.m_filterText); | 576 DEBUG_HIDE_EL(indent + L"HideEl::Found (tag/class) filter:" + classI
t->second.m_filterText); |
568 CPluginDebug::DebugResultHiding(tag, L"class:" + className, classIt-
>second.m_filterText); | 577 CPluginDebug::DebugResultHiding(tag, L"class:" + className, classIt-
>second.m_filterText); |
569 #endif | 578 #endif |
570 return true; | 579 return true; |
571 } | 580 } |
572 } | 581 } |
573 | 582 |
574 // Search general class name | 583 // Search general class name |
575 classItEnum = m_elementHideTagsClass.equal_range(std::make_pair(L"", cla
ssName)); | 584 classItEnum = m_elementHideTagsClass.equal_range(std::make_pair(L"", cla
ssName)); |
576 for (auto classIt = classItEnum.first; classIt != classItEnum.second; ++
classIt) | 585 for (auto classIt = classItEnum.first; classIt != classItEnum.second; ++
classIt) |
577 { | 586 { |
578 if (classIt->second.IsMatchFilterElementHide(pEl)) | 587 if (classIt->second.IsMatchFilterElementHide(pEl)) |
579 { | 588 { |
580 #ifdef ENABLE_DEBUG_RESULT | 589 #ifdef ENABLE_DEBUG_RESULT |
581 DEBUG_HIDE_EL(indent + L"HideEl::Found (?/class) filter:" + classIt-
>second.m_filterText); | 590 DEBUG_HIDE_EL(indent + L"HideEl::Found (?/class) filter:" + classIt-
>second.m_filterText); |
582 CPluginDebug::DebugResultHiding(tag, L"class:" + className, classIt-
>second.m_filterText); | 591 CPluginDebug::DebugResultHiding(tag, L"class:" + className, classIt-
>second.m_filterText); |
583 #endif | 592 #endif |
584 return true; | 593 return true; |
585 } | 594 } |
586 } | 595 } |
| 596 token = wcstok_s(nullptr, L" \t\n\r", &nextToken); |
587 } | 597 } |
588 } | 598 } |
589 | 599 |
590 // Search tag filters | 600 // Search tag filters |
591 auto tagItEnum = m_elementHideTags.equal_range(tag); | 601 auto tagItEnum = m_elementHideTags.equal_range(tag); |
592 for (auto tagIt = tagItEnum.first; tagIt != tagItEnum.second; ++ tagIt) | 602 for (auto tagIt = tagItEnum.first; tagIt != tagItEnum.second; ++tagIt) |
593 { | 603 { |
594 if (tagIt->second.IsMatchFilterElementHide(pEl)) | 604 if (tagIt->second.IsMatchFilterElementHide(pEl)) |
595 { | 605 { |
596 #ifdef ENABLE_DEBUG_RESULT | 606 #ifdef ENABLE_DEBUG_RESULT |
597 DEBUG_HIDE_EL(indent + L"HideEl::Found (tag) filter:" + tagIt->second.m_
filterText); | 607 DEBUG_HIDE_EL(indent + L"HideEl::Found (tag) filter:" + tagIt->second.m_
filterText); |
598 CPluginDebug::DebugResultHiding(tag, L"-", tagIt->second.m_filterText); | 608 CPluginDebug::DebugResultHiding(tag, L"-", tagIt->second.m_filterText); |
599 #endif | 609 #endif |
600 return true; | 610 return true; |
601 } | 611 } |
602 } | 612 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
644 | 654 |
645 void CPluginFilter::ClearFilters() | 655 void CPluginFilter::ClearFilters() |
646 { | 656 { |
647 // Clear filter maps | 657 // Clear filter maps |
648 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 658 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); |
649 m_elementHideTags.clear(); | 659 m_elementHideTags.clear(); |
650 m_elementHideTagsId.clear(); | 660 m_elementHideTagsId.clear(); |
651 m_elementHideTagsClass.clear(); | 661 m_elementHideTagsClass.clear(); |
652 } | 662 } |
653 | 663 |
654 bool CPluginFilter::ShouldBlock(const std::wstring& src, AdblockPlus::FilterEngi
ne::ContentType contentType, const std::wstring& domain, bool addDebug) const | |
655 { | |
656 std::wstring srcTrimmed = TrimString(src); | |
657 | |
658 // We should not block the empty string, so all filtering does not make sense | |
659 // Therefore we just return | |
660 if (srcTrimmed.empty()) | |
661 { | |
662 return false; | |
663 } | |
664 | |
665 CPluginSettings* settings = CPluginSettings::GetInstance(); | |
666 | |
667 CPluginClient* client = CPluginClient::GetInstance(); | |
668 bool result = client->Matches(srcTrimmed, contentType, domain); | |
669 | |
670 #ifdef ENABLE_DEBUG_RESULT | |
671 if (addDebug) | |
672 { | |
673 std::wstring type = ToUtf16String(AdblockPlus::FilterEngine::ContentTypeToSt
ring(contentType)); | |
674 if (result) | |
675 { | |
676 CPluginDebug::DebugResultBlocking(type, srcTrimmed, domain); | |
677 } | |
678 else | |
679 { | |
680 CPluginDebug::DebugResultIgnoring(type, srcTrimmed, domain); | |
681 } | |
682 } | |
683 #endif | |
684 return result; | |
685 } | |
LEFT | RIGHT |