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 | |
36 namespace | |
37 { | |
38 std::wstring ToLowerString(const std::wstring& s) | |
39 { | |
40 return ToWstring(ToCString(s).MakeLower()); | |
41 } | |
42 } | |
43 | 35 |
44 // ============================================================================ | 36 // ============================================================================ |
45 // CFilterElementHide | 37 // CFilterElementHide |
46 // ============================================================================ | 38 // ============================================================================ |
47 namespace | 39 namespace |
48 { | 40 { |
49 class ElementHideParseException | 41 class ElementHideParseException |
50 : public std::runtime_error | 42 : public std::runtime_error |
51 { | 43 { |
52 std::string message(const std::wstring& filterText, const std::string& reaso
n) | 44 std::string message(const std::wstring& filterText, const std::string& reaso
n) |
(...skipping 24 matching lines...) Expand all Loading... |
77 // Any tag | 69 // Any tag |
78 filterSuffix = filterSuffix.substr(1); | 70 filterSuffix = filterSuffix.substr(1); |
79 } | 71 } |
80 else if (firstTag == '[' || firstTag == '.' || firstTag == '#') | 72 else if (firstTag == '[' || firstTag == '.' || firstTag == '#') |
81 { | 73 { |
82 // Any tag (implicitly) | 74 // Any tag (implicitly) |
83 } | 75 } |
84 else if (isalnum(firstTag)) | 76 else if (isalnum(firstTag)) |
85 { | 77 { |
86 // Real tag | 78 // Real tag |
87 //TODO: Add support for descendant selectors | 79 // TODO: Add support for descendant selectors |
88 auto pos = filterSuffix.find_first_of(L".#[("); | 80 auto pos = filterSuffix.find_first_of(L".#[("); |
89 if (pos == std::wstring::npos) | 81 if (pos == std::wstring::npos) |
90 { | 82 { |
91 pos = filterSuffix.length(); | 83 pos = filterSuffix.length(); |
92 } | 84 } |
93 m_tag = ToLowerString(filterSuffix.substr(0, pos)); | 85 m_tag = ToLowerString(filterSuffix.substr(0, pos)); |
94 filterSuffix = filterSuffix.substr(pos); | 86 filterSuffix = filterSuffix.substr(pos); |
95 } | 87 } |
96 else | 88 else |
97 { | 89 { |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 std::wstring classNameList(ToWstring(classNameListBstr)); | 277 std::wstring classNameList(ToWstring(classNameListBstr)); |
286 if (classNameList.empty()) | 278 if (classNameList.empty()) |
287 { | 279 { |
288 return false; | 280 return false; |
289 } | 281 } |
290 // 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") |
291 /* | 283 /* |
292 * Match when 'm_tagClassName' appears as a token within classNameList | 284 * Match when 'm_tagClassName' appears as a token within classNameList |
293 */ | 285 */ |
294 bool foundMatch = false; | 286 bool foundMatch = false; |
295 TokenSequence<std::wstring> ts(classNameList, L" "); | 287 wchar_t* nextToken = nullptr; |
296 for (auto iterClassName = ts.cbegin(); iterClassName != ts.cend(); ++iterCla
ssName) | 288 const wchar_t* token = wcstok_s(&classNameList[0], L" ", &nextToken); |
297 { | 289 while (token != nullptr) |
298 if (*iterClassName == m_tagClassName) | 290 { |
| 291 if (std::wstring(token) == m_tagClassName) |
299 { | 292 { |
300 foundMatch = true; | 293 foundMatch = true; |
301 break; | 294 break; |
302 } | 295 } |
| 296 token = wcstok_s(nullptr, L" ", &nextToken); |
303 } | 297 } |
304 if (!foundMatch) | 298 if (!foundMatch) |
305 { | 299 { |
306 return false; | 300 return false; |
307 } | 301 } |
308 } | 302 } |
309 /* | 303 /* |
310 * If a tag name is specified, it must match | 304 * If a tag name is specified, it must match |
311 */ | 305 */ |
312 if (!m_tag.empty()) | 306 if (!m_tag.empty()) |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 CPluginDebug::DebugResultHiding(tag, L"id:" + id, idIt->second.m_filte
rText); | 556 CPluginDebug::DebugResultHiding(tag, L"id:" + id, idIt->second.m_filte
rText); |
563 #endif | 557 #endif |
564 return true; | 558 return true; |
565 } | 559 } |
566 } | 560 } |
567 } | 561 } |
568 | 562 |
569 // Search tag/className filters | 563 // Search tag/className filters |
570 if (!classNames.empty()) | 564 if (!classNames.empty()) |
571 { | 565 { |
572 TokenSequence<std::wstring> ts(classNames, L" \t\n\r"); | 566 wchar_t* nextToken = nullptr; |
573 for (auto iterClassName = ts.cbegin(); iterClassName != ts.cend(); ++iterC
lassName) | 567 const wchar_t* token = wcstok_s(&classNames[0], L" \t\n\r", &nextToken); |
574 { | 568 while (token != nullptr) |
575 std::wstring className = *iterClassName; | 569 { |
| 570 std::wstring className(token); |
576 auto classItEnum = m_elementHideTagsClass.equal_range(std::make_pair(tag
, className)); | 571 auto classItEnum = m_elementHideTagsClass.equal_range(std::make_pair(tag
, className)); |
577 for (auto classIt = classItEnum.first; classIt != classItEnum.second; ++
classIt) | 572 for (auto classIt = classItEnum.first; classIt != classItEnum.second; ++
classIt) |
578 { | 573 { |
579 if (classIt->second.IsMatchFilterElementHide(pEl)) | 574 if (classIt->second.IsMatchFilterElementHide(pEl)) |
580 { | 575 { |
581 #ifdef ENABLE_DEBUG_RESULT | 576 #ifdef ENABLE_DEBUG_RESULT |
582 DEBUG_HIDE_EL(indent + L"HideEl::Found (tag/class) filter:" + classI
t->second.m_filterText); | 577 DEBUG_HIDE_EL(indent + L"HideEl::Found (tag/class) filter:" + classI
t->second.m_filterText); |
583 CPluginDebug::DebugResultHiding(tag, L"class:" + className, classIt-
>second.m_filterText); | 578 CPluginDebug::DebugResultHiding(tag, L"class:" + className, classIt-
>second.m_filterText); |
584 #endif | 579 #endif |
585 return true; | 580 return true; |
586 } | 581 } |
587 } | 582 } |
588 | 583 |
589 // Search general class name | 584 // Search general class name |
590 classItEnum = m_elementHideTagsClass.equal_range(std::make_pair(L"", cla
ssName)); | 585 classItEnum = m_elementHideTagsClass.equal_range(std::make_pair(L"", cla
ssName)); |
591 for (auto classIt = classItEnum.first; classIt != classItEnum.second; ++
classIt) | 586 for (auto classIt = classItEnum.first; classIt != classItEnum.second; ++
classIt) |
592 { | 587 { |
593 if (classIt->second.IsMatchFilterElementHide(pEl)) | 588 if (classIt->second.IsMatchFilterElementHide(pEl)) |
594 { | 589 { |
595 #ifdef ENABLE_DEBUG_RESULT | 590 #ifdef ENABLE_DEBUG_RESULT |
596 DEBUG_HIDE_EL(indent + L"HideEl::Found (?/class) filter:" + classIt-
>second.m_filterText); | 591 DEBUG_HIDE_EL(indent + L"HideEl::Found (?/class) filter:" + classIt-
>second.m_filterText); |
597 CPluginDebug::DebugResultHiding(tag, L"class:" + className, classIt-
>second.m_filterText); | 592 CPluginDebug::DebugResultHiding(tag, L"class:" + className, classIt-
>second.m_filterText); |
598 #endif | 593 #endif |
599 return true; | 594 return true; |
600 } | 595 } |
601 } | 596 } |
| 597 token = wcstok_s(nullptr, L" \t\n\r", &nextToken); |
602 } | 598 } |
603 } | 599 } |
604 | 600 |
605 // Search tag filters | 601 // Search tag filters |
606 auto tagItEnum = m_elementHideTags.equal_range(tag); | 602 auto tagItEnum = m_elementHideTags.equal_range(tag); |
607 for (auto tagIt = tagItEnum.first; tagIt != tagItEnum.second; ++tagIt) | 603 for (auto tagIt = tagItEnum.first; tagIt != tagItEnum.second; ++tagIt) |
608 { | 604 { |
609 if (tagIt->second.IsMatchFilterElementHide(pEl)) | 605 if (tagIt->second.IsMatchFilterElementHide(pEl)) |
610 { | 606 { |
611 #ifdef ENABLE_DEBUG_RESULT | 607 #ifdef ENABLE_DEBUG_RESULT |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
659 | 655 |
660 void CPluginFilter::ClearFilters() | 656 void CPluginFilter::ClearFilters() |
661 { | 657 { |
662 // Clear filter maps | 658 // Clear filter maps |
663 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 659 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); |
664 m_elementHideTags.clear(); | 660 m_elementHideTags.clear(); |
665 m_elementHideTagsId.clear(); | 661 m_elementHideTagsId.clear(); |
666 m_elementHideTagsClass.clear(); | 662 m_elementHideTagsClass.clear(); |
667 } | 663 } |
668 | 664 |
669 bool CPluginFilter::ShouldBlock(const std::wstring& src, AdblockPlus::FilterEngi
ne::ContentType contentType, const std::wstring& domain, bool addDebug) const | |
670 { | |
671 std::wstring srcTrimmed = TrimString(src); | |
672 | |
673 // We should not block the empty string, so all filtering does not make sense | |
674 // Therefore we just return | |
675 if (srcTrimmed.empty()) | |
676 { | |
677 return false; | |
678 } | |
679 | |
680 CPluginSettings* settings = CPluginSettings::GetInstance(); | |
681 | |
682 CPluginClient* client = CPluginClient::GetInstance(); | |
683 bool result = client->Matches(srcTrimmed, contentType, domain); | |
684 | |
685 #ifdef ENABLE_DEBUG_RESULT | |
686 if (addDebug) | |
687 { | |
688 std::wstring type = ToUtf16String(AdblockPlus::FilterEngine::ContentTypeToSt
ring(contentType)); | |
689 if (result) | |
690 { | |
691 CPluginDebug::DebugResultBlocking(type, srcTrimmed, domain); | |
692 } | |
693 else | |
694 { | |
695 CPluginDebug::DebugResultIgnoring(type, srcTrimmed, domain); | |
696 } | |
697 } | |
698 #endif | |
699 return result; | |
700 } | |
LEFT | RIGHT |