Left: | ||
Right: |
OLD | NEW |
---|---|
1 #include "PluginStdAfx.h" | 1 #include "PluginStdAfx.h" |
2 | 2 |
3 #include "PluginFilter.h" | 3 #include "PluginFilter.h" |
4 | 4 |
5 #if (defined PRODUCT_ADBLOCKPLUS) | 5 #if (defined PRODUCT_ADBLOCKPLUS) |
6 #include "PluginSettings.h" | 6 #include "PluginSettings.h" |
7 #include "PluginClient.h" | 7 #include "PluginClient.h" |
8 #include "PluginClientFactory.h" | 8 #include "PluginClientFactory.h" |
9 #endif | 9 #endif |
10 | 10 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
73 | 73 |
74 CFilterElementHideAttrSelector::~CFilterElementHideAttrSelector() | 74 CFilterElementHideAttrSelector::~CFilterElementHideAttrSelector() |
75 { | 75 { |
76 } | 76 } |
77 | 77 |
78 | 78 |
79 // ============================================================================ | 79 // ============================================================================ |
80 // CFilterElementHide | 80 // CFilterElementHide |
81 // ============================================================================ | 81 // ============================================================================ |
82 | 82 |
83 CFilterElementHide::CFilterElementHide(const CString& filterText, const CString& filterFile) : m_filterText(filterText), m_filterFile(filterFile) | 83 CFilterElementHide::CFilterElementHide(const CString& filterText) : m_filterText (filterText) |
84 { | 84 { |
85 } | 85 } |
86 | 86 |
87 CFilterElementHide::CFilterElementHide(const CFilterElementHide& filter) | 87 CFilterElementHide::CFilterElementHide(const CFilterElementHide& filter) |
88 { | 88 { |
89 m_filterText = filter.m_filterText; | 89 m_filterText = filter.m_filterText; |
90 m_filterFile = filter.m_filterFile; | |
91 | 90 |
92 m_tagId = filter.m_tagId; | 91 m_tagId = filter.m_tagId; |
93 m_tagClassName = filter.m_tagClassName; | 92 m_tagClassName = filter.m_tagClassName; |
94 | 93 |
95 m_domainsNot = filter.m_domainsNot; | 94 m_domainsNot = filter.m_domainsNot; |
96 m_attributeSelectors = filter.m_attributeSelectors; | 95 m_attributeSelectors = filter.m_attributeSelectors; |
97 } | 96 } |
98 | 97 |
99 | 98 |
100 // ============================================================================ | 99 // ============================================================================ |
101 // CFilter | 100 // CFilter |
102 // ============================================================================ | 101 // ============================================================================ |
103 | 102 |
104 CFilter::CFilter(const CFilter& filter) | 103 CFilter::CFilter(const CFilter& filter) |
105 { | 104 { |
106 m_contentType = filter.m_contentType; | 105 m_contentType = filter.m_contentType; |
107 m_filterType = filter.m_filterType; | 106 m_filterType = filter.m_filterType; |
108 | 107 |
109 m_isFirstParty = filter.m_isFirstParty; | 108 m_isFirstParty = filter.m_isFirstParty; |
110 m_isThirdParty = filter.m_isThirdParty; | 109 m_isThirdParty = filter.m_isThirdParty; |
111 | 110 |
112 m_isMatchCase = filter.m_isMatchCase; | 111 m_isMatchCase = filter.m_isMatchCase; |
113 m_isFromStart = filter.m_isFromStart; | 112 m_isFromStart = filter.m_isFromStart; |
114 m_isFromStartDomain = filter.m_isFromStartDomain; | 113 m_isFromStartDomain = filter.m_isFromStartDomain; |
115 m_isFromEnd = filter.m_isFromEnd; | 114 m_isFromEnd = filter.m_isFromEnd; |
116 | 115 |
117 m_stringElements = filter.m_stringElements; | 116 m_stringElements = filter.m_stringElements; |
118 | 117 |
119 m_filterText = filter.m_filterText; | 118 m_filterText = filter.m_filterText; |
120 m_filterFile = filter.m_filterFile; | |
121 | 119 |
122 m_domains = filter.m_domains; | 120 m_domains = filter.m_domains; |
123 m_domainsNot = filter.m_domainsNot; | 121 m_domainsNot = filter.m_domainsNot; |
124 | 122 |
125 m_hitCount = filter.m_hitCount; | 123 m_hitCount = filter.m_hitCount; |
126 } | 124 } |
127 | 125 |
128 | 126 |
129 CFilter::CFilter() : m_isMatchCase(false), m_isFirstParty(false), m_isThirdParty (false), m_contentType(CFilter::contentTypeAny), | 127 CFilter::CFilter() : m_isMatchCase(false), m_isFirstParty(false), m_isThirdParty (false), m_contentType(CFilter::contentTypeAny), |
130 m_isFromStart(false), m_isFromStartDomain(false), m_isFromEnd(false), m_hitCou nt(0) | 128 m_isFromStart(false), m_isFromStartDomain(false), m_isFromEnd(false), m_hitCou nt(0) |
131 { | 129 { |
132 } | 130 } |
133 | 131 |
134 | 132 |
135 // ============================================================================ | 133 // ============================================================================ |
136 // CPluginFilter | 134 // CPluginFilter |
137 // ============================================================================ | 135 // ============================================================================ |
138 | 136 |
139 CPluginFilter::CPluginFilter(const TFilterFileList& list, const CString& dataPat h) : m_dataPath(dataPath) | 137 CPluginFilter::CPluginFilter(const CString& dataPath) : m_dataPath(dataPath) |
140 { | 138 { |
141 m_contentMap["document"] = CFilter::contentTypeDocument; | 139 m_contentMap["document"] = CFilter::contentTypeDocument; |
142 m_contentMap["subdocument"] = CFilter::contentTypeSubdocument; | 140 m_contentMap["subdocument"] = CFilter::contentTypeSubdocument; |
143 m_contentMap["sub-document"] = CFilter::contentTypeSubdocument; | 141 m_contentMap["sub-document"] = CFilter::contentTypeSubdocument; |
144 m_contentMap["sub_document"] = CFilter::contentTypeSubdocument; | 142 m_contentMap["sub_document"] = CFilter::contentTypeSubdocument; |
145 m_contentMap["other"] = CFilter::contentTypeOther; | 143 m_contentMap["other"] = CFilter::contentTypeOther; |
146 m_contentMap["image"] = CFilter::contentTypeImage; | 144 m_contentMap["image"] = CFilter::contentTypeImage; |
147 m_contentMap["script"] = CFilter::contentTypeScript; | 145 m_contentMap["script"] = CFilter::contentTypeScript; |
148 m_contentMap["object"] = CFilter::contentTypeObject; | 146 m_contentMap["object"] = CFilter::contentTypeObject; |
149 m_contentMap["object-subrequest"] = CFilter::contentTypeObjectSubrequest; | 147 m_contentMap["object-subrequest"] = CFilter::contentTypeObjectSubrequest; |
150 m_contentMap["object_subrequest"] = CFilter::contentTypeObjectSubrequest; | 148 m_contentMap["object_subrequest"] = CFilter::contentTypeObjectSubrequest; |
151 m_contentMap["xml-request"] = CFilter::contentTypeXmlHttpRequest; | 149 m_contentMap["xml-request"] = CFilter::contentTypeXmlHttpRequest; |
152 m_contentMap["xml_request"] = CFilter::contentTypeXmlHttpRequest; | 150 m_contentMap["xml_request"] = CFilter::contentTypeXmlHttpRequest; |
153 m_contentMap["xmlhttprequest"] = CFilter::contentTypeXmlHttpRequest; | 151 m_contentMap["xmlhttprequest"] = CFilter::contentTypeXmlHttpRequest; |
154 m_contentMap["stylesheet"] = CFilter::contentTypeStyleSheet; | 152 m_contentMap["stylesheet"] = CFilter::contentTypeStyleSheet; |
155 m_contentMap["background"] = CFilter::contentTypeBackground; | 153 m_contentMap["background"] = CFilter::contentTypeBackground; |
156 | 154 |
157 m_contentMapText[CFilter::contentTypeDocument] = "doc"; | 155 m_contentMapText[CFilter::contentTypeDocument] = "doc"; |
158 m_contentMapText[CFilter::contentTypeObject] = "object"; | 156 m_contentMapText[CFilter::contentTypeObject] = "object"; |
159 m_contentMapText[CFilter::contentTypeImage] = "img"; | 157 m_contentMapText[CFilter::contentTypeImage] = "img"; |
160 m_contentMapText[CFilter::contentTypeScript] = "script"; | 158 m_contentMapText[CFilter::contentTypeScript] = "script"; |
161 m_contentMapText[CFilter::contentTypeOther] = "other"; | 159 m_contentMapText[CFilter::contentTypeOther] = "other"; |
162 m_contentMapText[CFilter::contentTypeUnknown] = "?"; | 160 m_contentMapText[CFilter::contentTypeUnknown] = "?"; |
163 m_contentMapText[CFilter::contentTypeSubdocument] = "iframe"; | 161 m_contentMapText[CFilter::contentTypeSubdocument] = "iframe"; |
164 m_contentMapText[CFilter::contentTypeStyleSheet] = "css"; | 162 m_contentMapText[CFilter::contentTypeStyleSheet] = "css"; |
165 | 163 |
166 ParseFilters(list); | 164 ClearFilters(); |
167 } | 165 } |
168 | 166 |
169 | 167 |
170 CPluginFilter::CPluginFilter(const CString& dataPath) : m_dataPath(dataPath) | 168 bool CPluginFilter::AddFilterElementHide(CString filterText) |
171 { | |
172 } | |
173 | |
174 | |
175 bool CPluginFilter::AddFilterElementHide(CString filterText, CString filterFile) | |
176 { | 169 { |
177 int delimiterPos = filterText.Find(L"#"); | 170 int delimiterPos = filterText.Find(L"#"); |
178 if (delimiterPos < 0 || filterText.GetLength() <= delimiterPos + 1) | 171 if (delimiterPos < 0 || filterText.GetLength() <= delimiterPos + 1) |
179 { | 172 { |
180 DEBUG_FILTER("Filter::Error parsing filter:" + filterFile + "/" + filterText + " (no tag)") | 173 DEBUG_FILTER("Filter::Error parsing filter:" + filterFile + "/" + filterText + " (no tag)") |
181 return false; | 174 return false; |
182 } | 175 } |
183 DEBUG_FILTER("Input: " + filterText + " filterFile" + filterFile); | 176 DEBUG_FILTER("Input: " + filterText + " filterFile" + filterFile); |
184 bool isOldFormat = true; | 177 bool isOldFormat = true; |
185 if (filterText.GetAt(delimiterPos + 1) == '#') | 178 if (filterText.GetAt(delimiterPos + 1) == '#') |
186 { | 179 { |
187 isOldFormat = false; | 180 isOldFormat = false; |
188 } | 181 } |
189 | 182 |
190 s_criticalSectionFilterMap.Lock(); | 183 s_criticalSectionFilterMap.Lock(); |
191 { | 184 { |
192 // Create filter descriptor | 185 // Create filter descriptor |
193 CFilterElementHide filter(filterText, filterFile); | 186 CFilterElementHide filter(filterText); |
194 | 187 |
195 CString filterDomains = filterText.Left(delimiterPos).MakeLower(); | 188 CString filterDomains = filterText.Left(delimiterPos).MakeLower(); |
196 CString filterString = filterText.Right(filterText.GetLength() - delimiterP os - (isOldFormat ? 1 : 2)); | 189 CString filterString = filterText.Right(filterText.GetLength() - delimiterP os - (isOldFormat ? 1 : 2)); |
197 | 190 |
198 bool isDomainSpecific = delimiterPos > 0 && filterDomains.Find('~') < 0; | 191 bool isDomainSpecific = delimiterPos > 0 && filterDomains.Find('~') < 0; |
199 | 192 |
200 // Add not-domains to filter | 193 // Add not-domains to filter |
201 if (!isDomainSpecific && delimiterPos > 0) | 194 if (!isDomainSpecific && delimiterPos > 0) |
202 { | 195 { |
203 int endPos = 0; | 196 int endPos = 0; |
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
637 // Check all classes | 630 // Check all classes |
638 if (classNames == filterIt->second.m_tagClassName || filterIt->secon d.m_tagClassName.IsEmpty()) | 631 if (classNames == filterIt->second.m_tagClassName || filterIt->secon d.m_tagClassName.IsEmpty()) |
639 { | 632 { |
640 isHidden = IsMatchFilterElementHide(filterIt->second, pEl, domain) ; | 633 isHidden = IsMatchFilterElementHide(filterIt->second, pEl, domain) ; |
641 #ifdef ENABLE_DEBUG_RESULT | 634 #ifdef ENABLE_DEBUG_RESULT |
642 if (isHidden) | 635 if (isHidden) |
643 { | 636 { |
644 if (!id.IsEmpty() && !classNames.IsEmpty()) | 637 if (!id.IsEmpty() && !classNames.IsEmpty()) |
645 { | 638 { |
646 DEBUG_HIDE_EL(indent + "HideEl::Found (domain) filter:" + filt erIt->second.m_filterText) | 639 DEBUG_HIDE_EL(indent + "HideEl::Found (domain) filter:" + filt erIt->second.m_filterText) |
647 CPluginDebug::DebugResultHiding(tag, "id:" + id + " class:" + classNames, filterIt->second.m_filterText, filterIt->second.m_filterFile); | 640 CPluginDebug::DebugResultHiding(tag, "id:" + id + " class:" + classNames, filterIt->second.m_filterText); |
648 } | 641 } |
649 else if (!id.IsEmpty()) | 642 else if (!id.IsEmpty()) |
650 { | 643 { |
651 DEBUG_HIDE_EL(indent + "HideEl::Found (domain) filter:" + filt erIt->second.m_filterText) | 644 DEBUG_HIDE_EL(indent + "HideEl::Found (domain) filter:" + filt erIt->second.m_filterText) |
652 CPluginDebug::DebugResultHiding(tag, "id:" + id, filterIt->s econd.m_filterText, filterIt->second.m_filterFile); | 645 CPluginDebug::DebugResultHiding(tag, "id:" + id, filterIt->s econd.m_filterText); |
653 } | 646 } |
654 else if (!classNames.IsEmpty()) | 647 else if (!classNames.IsEmpty()) |
655 { | 648 { |
656 DEBUG_HIDE_EL(indent + "HideEl::Found (domain) filter:" + filt erIt->second.m_filterText) | 649 DEBUG_HIDE_EL(indent + "HideEl::Found (domain) filter:" + filt erIt->second.m_filterText) |
657 CPluginDebug::DebugResultHiding(tag, "class:" + classNames, filterIt->second.m_filterText, filterIt->second.m_filterFile); | 650 CPluginDebug::DebugResultHiding(tag, "class:" + classNames, filterIt->second.m_filterText); |
658 } | 651 } |
659 else | 652 else |
660 { | 653 { |
661 DEBUG_HIDE_EL(indent + "HideEl::Found (domain) filter:" + filt erIt->second.m_filterText) | 654 DEBUG_HIDE_EL(indent + "HideEl::Found (domain) filter:" + filt erIt->second.m_filterText) |
662 CPluginDebug::DebugResultHiding(tag, "-" + classNames, filte rIt->second.m_filterText, filterIt->second.m_filterFile); | 655 CPluginDebug::DebugResultHiding(tag, "-" + classNames, filte rIt->second.m_filterText); |
663 } | 656 } |
664 } | 657 } |
665 #endif | 658 #endif |
666 } | 659 } |
667 | 660 |
668 // Iterate through class names | 661 // Iterate through class names |
669 if (isHidden == false && !classNames.IsEmpty() && !filterIt->second. m_tagClassName.IsEmpty() && classNames.Find(' ') > 0) | 662 if (isHidden == false && !classNames.IsEmpty() && !filterIt->second. m_tagClassName.IsEmpty() && classNames.Find(' ') > 0) |
670 { | 663 { |
671 int pos = 0; | 664 int pos = 0; |
672 CString className = classNames.Tokenize(L" \t\n\r", pos); | 665 CString className = classNames.Tokenize(L" \t\n\r", pos); |
673 | 666 |
674 while (isHidden == false && pos >= 0) | 667 while (isHidden == false && pos >= 0) |
675 { | 668 { |
676 if (className == filterIt->second.m_tagClassName) | 669 if (className == filterIt->second.m_tagClassName) |
677 { | 670 { |
678 isHidden = IsMatchFilterElementHide(filterIt->second, pEl, dom ain); | 671 isHidden = IsMatchFilterElementHide(filterIt->second, pEl, dom ain); |
679 #ifdef ENABLE_DEBUG_RESULT | 672 #ifdef ENABLE_DEBUG_RESULT |
680 if (isHidden) | 673 if (isHidden) |
681 { | 674 { |
682 if (!id.IsEmpty()) | 675 if (!id.IsEmpty()) |
683 { | 676 { |
684 DEBUG_HIDE_EL(indent + "HideEl::Found (domain) filter:" + filterIt->second.m_filterText) | 677 DEBUG_HIDE_EL(indent + "HideEl::Found (domain) filter:" + filterIt->second.m_filterText) |
685 CPluginDebug::DebugResultHiding(tag, "id:" + id + " clas s:" + classNames, filterIt->second.m_filterText, filterIt->second.m_filterFile); | 678 CPluginDebug::DebugResultHiding(tag, "id:" + id + " clas s:" + classNames, filterIt->second.m_filterText); |
686 } | 679 } |
687 else | 680 else |
688 { | 681 { |
689 DEBUG_HIDE_EL(indent + "HideEl::Found (domain) filter:" + filterIt->second.m_filterText) | 682 DEBUG_HIDE_EL(indent + "HideEl::Found (domain) filter:" + filterIt->second.m_filterText) |
690 CPluginDebug::DebugResultHiding(tag, "-" + classNames, f ilterIt->second.m_filterText, filterIt->second.m_filterFile); | 683 CPluginDebug::DebugResultHiding(tag, "-" + classNames, f ilterIt->second.m_filterText); |
691 } | 684 } |
692 } | 685 } |
693 #endif | 686 #endif |
694 } | 687 } |
695 | 688 |
696 // Next class name | 689 // Next class name |
697 className = classNames.Tokenize(L" \t\n\r", pos); | 690 className = classNames.Tokenize(L" \t\n\r", pos); |
698 } | 691 } |
699 } | 692 } |
700 } | 693 } |
(...skipping 14 matching lines...) Expand all Loading... | |
715 if (isHidden == false && !id.IsEmpty()) | 708 if (isHidden == false && !id.IsEmpty()) |
716 { | 709 { |
717 TFilterElementHideTagsNamed::const_iterator idIt = m_elementHideTagsId.fin d(std::make_pair(tag, id)); | 710 TFilterElementHideTagsNamed::const_iterator idIt = m_elementHideTagsId.fin d(std::make_pair(tag, id)); |
718 if (idIt != m_elementHideTagsId.end()) | 711 if (idIt != m_elementHideTagsId.end()) |
719 { | 712 { |
720 isHidden = IsMatchFilterElementHide(idIt->second, pEl, domain); | 713 isHidden = IsMatchFilterElementHide(idIt->second, pEl, domain); |
721 #ifdef ENABLE_DEBUG_RESULT | 714 #ifdef ENABLE_DEBUG_RESULT |
722 if (isHidden) | 715 if (isHidden) |
723 { | 716 { |
724 DEBUG_HIDE_EL(indent + "HideEl::Found (tag/id) filter:" + idIt->second .m_filterText) | 717 DEBUG_HIDE_EL(indent + "HideEl::Found (tag/id) filter:" + idIt->second .m_filterText) |
725 CPluginDebug::DebugResultHiding(tag, "id:" + id, idIt->second.m_filt erText, idIt->second.m_filterFile); | 718 CPluginDebug::DebugResultHiding(tag, "id:" + id, idIt->second.m_filt erText); |
726 } | 719 } |
727 #endif | 720 #endif |
728 } | 721 } |
729 | 722 |
730 // Search general id | 723 // Search general id |
731 if (isHidden == false) | 724 if (isHidden == false) |
732 { | 725 { |
733 idIt = m_elementHideTagsId.find(std::make_pair("", id)); | 726 idIt = m_elementHideTagsId.find(std::make_pair("", id)); |
734 if (idIt != m_elementHideTagsId.end()) | 727 if (idIt != m_elementHideTagsId.end()) |
735 { | 728 { |
736 isHidden = IsMatchFilterElementHide(idIt->second, pEl, domain); | 729 isHidden = IsMatchFilterElementHide(idIt->second, pEl, domain); |
737 #ifdef ENABLE_DEBUG_RESULT | 730 #ifdef ENABLE_DEBUG_RESULT |
738 if (isHidden) | 731 if (isHidden) |
739 { | 732 { |
740 DEBUG_HIDE_EL(indent + "HideEl::Found (?/id) filter:" + idIt->second .m_filterText) | 733 DEBUG_HIDE_EL(indent + "HideEl::Found (?/id) filter:" + idIt->second .m_filterText) |
741 CPluginDebug::DebugResultHiding(tag, "id:" + id, idIt->second.m_fi lterText, idIt->second.m_filterFile); | 734 CPluginDebug::DebugResultHiding(tag, "id:" + id, idIt->second.m_fi lterText); |
742 } | 735 } |
743 #endif | 736 #endif |
744 } | 737 } |
745 } | 738 } |
746 } | 739 } |
747 | 740 |
748 // Search tag/className filters | 741 // Search tag/className filters |
749 if (isHidden == false && !classNames.IsEmpty()) | 742 if (isHidden == false && !classNames.IsEmpty()) |
750 { | 743 { |
751 int pos = 0; | 744 int pos = 0; |
752 CString className = classNames.Tokenize(L" \t\n\r", pos); | 745 CString className = classNames.Tokenize(L" \t\n\r", pos); |
753 | 746 |
754 while (isHidden == false && pos >= 0) | 747 while (isHidden == false && pos >= 0) |
755 { | 748 { |
756 TFilterElementHideTagsNamed::const_iterator classIt = m_elementHideTagsC lass.find(std::make_pair(tag, className)); | 749 TFilterElementHideTagsNamed::const_iterator classIt = m_elementHideTagsC lass.find(std::make_pair(tag, className)); |
757 if (classIt != m_elementHideTagsClass.end()) | 750 if (classIt != m_elementHideTagsClass.end()) |
758 { | 751 { |
759 isHidden = IsMatchFilterElementHide(classIt->second, pEl, domain); | 752 isHidden = IsMatchFilterElementHide(classIt->second, pEl, domain); |
760 #ifdef ENABLE_DEBUG_RESULT | 753 #ifdef ENABLE_DEBUG_RESULT |
761 if (isHidden) | 754 if (isHidden) |
762 { | 755 { |
763 DEBUG_HIDE_EL(indent + "HideEl::Found (tag/class) filter:" + classIt ->second.m_filterText) | 756 DEBUG_HIDE_EL(indent + "HideEl::Found (tag/class) filter:" + classIt ->second.m_filterText) |
764 CPluginDebug::DebugResultHiding(tag, "class:" + className, classIt ->second.m_filterText, classIt->second.m_filterFile); | 757 CPluginDebug::DebugResultHiding(tag, "class:" + className, classIt ->second.m_filterText); |
765 } | 758 } |
766 #endif | 759 #endif |
767 } | 760 } |
768 | 761 |
769 // Search general class name | 762 // Search general class name |
770 if (isHidden == false) | 763 if (isHidden == false) |
771 { | 764 { |
772 classIt = m_elementHideTagsClass.find(std::make_pair("", className)); | 765 classIt = m_elementHideTagsClass.find(std::make_pair("", className)); |
773 if (classIt != m_elementHideTagsClass.end()) | 766 if (classIt != m_elementHideTagsClass.end()) |
774 { | 767 { |
775 isHidden = IsMatchFilterElementHide(classIt->second, pEl, domain); | 768 isHidden = IsMatchFilterElementHide(classIt->second, pEl, domain); |
776 #ifdef ENABLE_DEBUG_RESULT | 769 #ifdef ENABLE_DEBUG_RESULT |
777 if (isHidden) | 770 if (isHidden) |
778 { | 771 { |
779 DEBUG_HIDE_EL(indent + "HideEl::Found (?/class) filter:" + classIt ->second.m_filterText) | 772 DEBUG_HIDE_EL(indent + "HideEl::Found (?/class) filter:" + classIt ->second.m_filterText) |
780 CPluginDebug::DebugResultHiding(tag, "class:" + className, class It->second.m_filterText, classIt->second.m_filterFile); | 773 CPluginDebug::DebugResultHiding(tag, "class:" + className, class It->second.m_filterText); |
781 } | 774 } |
782 #endif | 775 #endif |
783 } | 776 } |
784 } | 777 } |
785 | 778 |
786 // Next class name | 779 // Next class name |
787 className = classNames.Tokenize(L" \t\n\r", pos); | 780 className = classNames.Tokenize(L" \t\n\r", pos); |
788 } | 781 } |
789 } | 782 } |
790 | 783 |
791 // Search tag filters | 784 // Search tag filters |
792 if (isHidden == false) | 785 if (isHidden == false) |
793 { | 786 { |
794 TFilterElementHideTags::const_iterator tagIt = m_elementHideTags.find(tag) ; | 787 TFilterElementHideTags::const_iterator tagIt = m_elementHideTags.find(tag) ; |
795 if (tagIt != m_elementHideTags.end()) | 788 if (tagIt != m_elementHideTags.end()) |
796 { | 789 { |
797 isHidden = IsMatchFilterElementHide(tagIt->second, pEl, domain); | 790 isHidden = IsMatchFilterElementHide(tagIt->second, pEl, domain); |
798 #ifdef ENABLE_DEBUG_RESULT | 791 #ifdef ENABLE_DEBUG_RESULT |
799 if (isHidden) | 792 if (isHidden) |
800 { | 793 { |
801 DEBUG_HIDE_EL(indent + "HideEl::Found (tag) filter:" + tagIt->second.m _filterText) | 794 DEBUG_HIDE_EL(indent + "HideEl::Found (tag) filter:" + tagIt->second.m _filterText) |
802 CPluginDebug::DebugResultHiding(tag, "-", tagIt->second.m_filterText , tagIt->second.m_filterFile); | 795 CPluginDebug::DebugResultHiding(tag, "-", tagIt->second.m_filterText ); |
803 } | 796 } |
804 #endif | 797 #endif |
805 } | 798 } |
806 } | 799 } |
807 } | 800 } |
808 s_criticalSectionFilterMap.Unlock(); | 801 s_criticalSectionFilterMap.Unlock(); |
809 | 802 |
810 return isHidden; | 803 return isHidden; |
811 } | 804 } |
812 | 805 |
813 | 806 bool CPluginFilter::LoadHideFilters(std::vector<std::string> filters) |
814 void CPluginFilter::AddFilter(CString filterString, CString filterFile, int filt erType) | |
815 { | |
816 //We don't accept too short filters. Those are suspicious. | |
817 if (filterString.GetLength() < 5) | |
818 return; | |
819 | |
820 CString raw = filterString; | |
821 | |
822 // Here we should find a key for the filter | |
823 // We find a string of max 8 characters that does not contain any wildcards an d which are unique for the filter | |
824 | |
825 // Find settings part, identified by $ | |
826 CString filterSettings; | |
827 | |
828 int pos = filterString.Find('$'); | |
829 if (pos > 0) | |
830 { | |
831 filterSettings = filterString.Right(filterString.GetLength() - pos - 1); | |
832 filterString = filterString.Left(pos); | |
833 } | |
834 | |
835 // Split filterString to parts | |
836 | |
837 bool bCheckFromStartDomain = false; | |
838 if (filterString.Find(L"||") == 0) | |
839 { | |
840 bCheckFromStartDomain = true; | |
841 filterString = filterString.Right(filterString.GetLength() - 2); | |
842 } | |
843 | |
844 bool bCheckFromStart = false; | |
845 if (filterString.GetAt(0) == '|') | |
846 { | |
847 bCheckFromStart = true; | |
848 filterString = filterString.Right(filterString.GetLength() - 1); | |
849 } | |
850 | |
851 bool bCheckFromEnd = false; | |
852 if (filterString.Right(1) == "|") | |
853 { | |
854 bCheckFromEnd = true; | |
855 filterString = filterString.Left(filterString.GetLength() - 1); | |
856 } | |
857 | |
858 std::vector<CString> filterParts; | |
859 pos = 0; | |
860 | |
861 while ((pos = filterString.Find('*')) >= 0) | |
862 { | |
863 if (pos > 0) | |
864 { | |
865 filterParts.push_back(filterString.Left(pos)); | |
866 } | |
867 filterString = filterString.Right(filterString.GetLength() - pos - 1); | |
868 } | |
869 | |
870 if (!filterString.IsEmpty()) | |
871 { | |
872 filterParts.push_back(filterString); | |
873 } | |
874 | |
875 TFilterMap* filterMap = m_filterMap[filterType]; | |
876 | |
877 // Define hash key | |
878 DWORD dwKey = 0; | |
879 DWORD dwKeyMap = 0; | |
880 | |
881 int keyLength = 4; | |
882 int startCharacter = 0; | |
883 if (filterParts.size() < 1) | |
884 { | |
885 return; | |
886 } | |
887 CString filterPart = filterParts[0]; | |
888 filterPart.MakeLower(); | |
889 | |
890 int nFilterParts = filterParts.size(); | |
891 int nFilterPart = 0; | |
892 | |
893 int filterPartLength = filterPart.GetLength(); | |
894 | |
895 if (filterPartLength >= 7) | |
896 { | |
897 if (filterPart.Find(L"http://") == 0) | |
898 { | |
899 startCharacter = 7; | |
900 } | |
901 else if (filterPart.Find(L"https://") == 0) | |
902 { | |
903 startCharacter = 8; | |
904 } | |
905 } | |
906 | |
907 while (true) | |
908 { | |
909 // Part is too short as unique key? - try next filter part | |
910 while (filterPartLength < startCharacter + keyLength) | |
911 { | |
912 nFilterPart++; | |
913 if (nFilterPart >= nFilterParts) | |
914 { | |
915 break; | |
916 } | |
917 | |
918 filterPart = filterParts[nFilterPart]; | |
919 filterPart.MakeLower(); | |
920 filterPartLength = filterPart.GetLength(); | |
921 | |
922 startCharacter = 0; | |
923 } | |
924 | |
925 if (nFilterPart >= nFilterParts) | |
926 { | |
927 break; | |
928 } | |
929 | |
930 int posSpecial = filterPart.Find('^', startCharacter); | |
931 if (posSpecial >= 0 && posSpecial < startCharacter + keyLength) | |
932 { | |
933 startCharacter = posSpecial + 1; | |
934 } | |
935 else | |
936 { | |
937 // Try key | |
938 DWORD dwTestKey = (filterPart.GetAt(startCharacter) << 24) | (filterPart.G etAt(startCharacter+1) << 16) | (filterPart.GetAt(startCharacter+2) << 8) | filt erPart.GetAt(startCharacter+3); | |
939 | |
940 // Now we have a substring which we can check | |
941 if (filterMap[0].find(dwTestKey) == filterMap[0].end()) | |
942 { | |
943 dwKey = dwTestKey; | |
944 dwKeyMap = 0; | |
945 break; | |
946 } | |
947 | |
948 // We already had a match - increment the start character | |
949 startCharacter++; | |
950 } | |
951 } | |
952 | |
953 // Try second list | |
954 if (dwKey == 0) | |
955 { | |
956 dwKeyMap = 1; | |
957 | |
958 startCharacter = 0; | |
959 | |
960 filterPart = filterParts[0]; | |
961 filterPart.MakeLower(); | |
962 filterPartLength = filterPart.GetLength(); | |
963 | |
964 nFilterPart = 0; | |
965 | |
966 if (filterPartLength >= 7) | |
967 { | |
968 if (filterPart.Find(L"http://") == 0) | |
969 { | |
970 startCharacter = 7; | |
971 } | |
972 else if (filterPart.Find(L"https://") == 0) | |
973 { | |
974 startCharacter = 8; | |
975 } | |
976 } | |
977 | |
978 while (true) | |
979 { | |
980 // Part is too short as unique key? - try next filter part | |
981 while (filterPartLength < startCharacter + keyLength) | |
982 { | |
983 nFilterPart++; | |
984 if (nFilterPart >= nFilterParts) | |
985 { | |
986 break; | |
987 } | |
988 | |
989 filterPart = filterParts[nFilterPart]; | |
990 filterPart.MakeLower(); | |
991 filterPartLength = filterPart.GetLength(); | |
992 | |
993 startCharacter = 0; | |
994 } | |
995 | |
996 if (nFilterPart >= nFilterParts) | |
997 { | |
998 break; | |
999 } | |
1000 | |
1001 int posSpecial = filterPart.Find('^', startCharacter); | |
1002 if (posSpecial >= 0 && posSpecial < startCharacter + keyLength) | |
1003 { | |
1004 startCharacter = posSpecial + 1; | |
1005 } | |
1006 else | |
1007 { | |
1008 // Try key | |
1009 DWORD dwTestKey = (filterPart.GetAt(startCharacter) << 24) | (filterPart .GetAt(startCharacter+1) << 16) | (filterPart.GetAt(startCharacter+2) << 8) | fi lterPart.GetAt(startCharacter+3); | |
1010 | |
1011 // Now we have a substring which we can check | |
1012 if (filterMap[1].find(dwTestKey) == filterMap[1].end()) | |
1013 { | |
1014 dwKey = dwTestKey; | |
1015 break; | |
1016 } | |
1017 | |
1018 // We already had a match - increment the start character | |
1019 startCharacter++; | |
1020 } | |
1021 } | |
1022 } | |
1023 | |
1024 // Create the filter | |
1025 CFilter filter; | |
1026 filter.m_filterType = CFilter::filterTypeBlocking; | |
1027 filter.m_stringElements = filterParts; | |
1028 filter.m_isFromStart = bCheckFromStart; | |
1029 filter.m_isFromStartDomain = bCheckFromStartDomain; | |
1030 filter.m_isFromEnd = bCheckFromEnd; | |
1031 filter.m_filterText = raw; | |
1032 filter.m_filterFile = filterFile; | |
1033 | |
1034 // Set content type of filter and other settings | |
1035 if (!filterSettings.IsEmpty()) | |
1036 { | |
1037 // Split filterSettings to parts | |
1038 pos = 0; | |
1039 bool hasContent = false; | |
1040 | |
1041 while ((pos = filterSettings.Find(',')) >= 0 || !filterSettings.IsEmpty()) | |
1042 { | |
1043 CString setting = pos >= 0 ? filterSettings.Left(pos) : filterSettings; | |
1044 filterSettings = pos >= 0 ? filterSettings.Right(filterSettings.GetLength( ) - pos - 1) : ""; | |
1045 | |
1046 // Is content type negated | |
1047 bool bNegate = false; | |
1048 if (setting.GetAt(0) == '~') | |
1049 { | |
1050 bNegate = true; | |
1051 setting = setting.Right(setting.GetLength() - 1); | |
1052 } | |
1053 | |
1054 // Apply content type | |
1055 std::map<CString, int>::iterator it = m_contentMap.find(setting); | |
1056 if (it != m_contentMap.end()) | |
1057 { | |
1058 if (!hasContent) | |
1059 { | |
1060 if (bNegate) | |
1061 { | |
1062 filter.m_contentType = ~it->second; | |
1063 } | |
1064 else | |
1065 { | |
1066 filter.m_contentType = it->second; | |
1067 } | |
1068 hasContent = true; | |
1069 } | |
1070 else if (bNegate) | |
1071 { | |
1072 filter.m_contentType &= ~it->second; | |
1073 } | |
1074 else | |
1075 { | |
1076 filter.m_contentType |= it->second; | |
1077 } | |
1078 } | |
1079 else if (setting == "match-case") | |
1080 { | |
1081 filter.m_isMatchCase = true; | |
1082 } | |
1083 else if (setting == "third-party") | |
1084 { | |
1085 if (bNegate) | |
1086 { | |
1087 filter.m_isFirstParty = true; | |
1088 } | |
1089 else | |
1090 { | |
1091 filter.m_isThirdParty = true; | |
1092 } | |
1093 } | |
1094 else if (setting.Left(7) == "domain=") | |
1095 { | |
1096 int posDomain = 0; | |
1097 setting = setting.Right(setting.GetLength() - 7); | |
1098 | |
1099 while ((posDomain = setting.Find('|')) >= 0 || !setting.IsEmpty()) | |
1100 { | |
1101 CString domain = posDomain >= 0 ? setting.Left(posDomain) : setting; | |
1102 setting = posDomain >= 0 ? setting.Right(setting.GetLength() - posDoma in - 1) : ""; | |
1103 | |
1104 if (domain.GetAt(0) == '~') | |
1105 { | |
1106 domain = domain.Right(domain.GetLength() - 1); | |
1107 | |
1108 filter.m_domainsNot.insert(domain); | |
1109 } | |
1110 else | |
1111 { | |
1112 filter.m_domains.insert(domain); | |
1113 } | |
1114 } | |
1115 } | |
1116 else | |
1117 { | |
1118 DEBUG_FILTER("Filter::Error parsing filter:" + filterFile + "/" + raw + " (unhandled tag: " + setting + ")") | |
1119 return; | |
1120 } | |
1121 } | |
1122 } | |
1123 | |
1124 // Add the filter | |
1125 if (dwKey != 0) | |
1126 { | |
1127 filterMap[dwKeyMap][dwKey] = filter; | |
1128 } | |
1129 else | |
1130 { | |
1131 m_filterMapDefault[filterType].push_back(filter); | |
1132 } | |
1133 } | |
1134 | |
1135 #ifdef PRODUCT_ADBLOCKPLUS | |
1136 | |
1137 bool CPluginFilter::DownloadFilterFile(const CString& url, const CString& filena me) | |
1138 { | |
1139 CString tempFile = CPluginSettings::GetTempFile(TEMP_FILE_PREFIX); | |
1140 | |
1141 DEBUG_GENERAL("*** Downloading filter file:" + filename + " (to " + tempFile + ")"); | |
1142 | |
1143 bool bResult = !tempFile.IsEmpty(); | |
1144 if (bResult) | |
1145 { | |
1146 // if new filter urls are found download them and update the persistent data | |
1147 HRESULT hr = ::URLDownloadToFile(NULL, url, tempFile, 0, NULL); | |
1148 if (SUCCEEDED(hr)) | |
1149 { | |
1150 CPluginFilterLock lock(filename); | |
1151 if (lock.IsLocked()) | |
1152 { | |
1153 // Move the temporary file to the new text file. | |
1154 if (!::MoveFileEx(tempFile, CPluginSettings::GetDataPath(filename), MOVE FILE_REPLACE_EXISTING)) | |
1155 { | |
1156 DWORD dwError = ::GetLastError(); | |
1157 | |
1158 // Not same device? copy/delete instead | |
1159 if (dwError == ERROR_NOT_SAME_DEVICE) | |
1160 { | |
1161 if (!::CopyFile(tempFile, CPluginSettings::GetDataPath(filename), FA LSE)) | |
1162 { | |
1163 DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_FILTER, PLUGIN_ERRO R_FILTER_COPY_FILE, "Filter::Unable to copy file:" + filename) | |
1164 | |
1165 bResult = false; | |
1166 } | |
1167 | |
1168 ::DeleteFile(tempFile); | |
1169 } | |
1170 else | |
1171 { | |
1172 DEBUG_ERROR_LOG(dwError, PLUGIN_ERROR_FILTER, PLUGIN_ERROR_FILTER_MO VE_FILE, "Filter::Unable to replace file:" + filename) | |
1173 | |
1174 bResult = false; | |
1175 } | |
1176 } | |
1177 } | |
1178 else | |
1179 { | |
1180 bResult = false; | |
1181 } | |
1182 } | |
1183 else | |
1184 { | |
1185 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_FILTER, PLUGIN_ERROR_FILTER_DOWNLOAD_FILE , "Filter::Unable to download file: " + filename) | |
1186 | |
1187 bResult = false; | |
1188 } | |
1189 } | |
1190 | |
1191 return bResult; | |
1192 } | |
1193 | |
1194 #endif | |
1195 | |
1196 bool CPluginFilter::ReadFilter(const CString& filename, const CString& downloadP ath) | |
1197 { | 807 { |
1198 bool isRead = false; | 808 bool isRead = false; |
1199 | 809 |
1200 #ifdef PRODUCT_ADBLOCKPLUS | 810 #ifdef PRODUCT_ADBLOCKPLUS |
1201 CPluginClient* client = CPluginClient::GetInstance(); | 811 CPluginClient* client = CPluginClient::GetInstance(); |
1202 #endif | 812 #endif |
1203 CString fileContent; | |
1204 | 813 |
1205 #ifdef PRODUCT_ADBLOCKPLUS | 814 // Parse hide string |
1206 CPluginFilterLock lock(filename); | 815 int pos = 0; |
1207 if (lock.IsLocked()) | 816 |
817 s_criticalSectionFilterMap.Lock(); | |
1208 { | 818 { |
1209 #endif | 819 for (std::vector<std::string>::iterator it = filters.begin(); it < filters.e nd(); ++it) |
1210 DEBUG_GENERAL("*** Loading filter:" + m_dataPath + filename); | 820 { |
821 CString filter((*it).c_str()); | |
822 // If the line is not commented out | |
823 if (!filter.Trim().IsEmpty() && filter.GetAt(0) != '!' && filter.GetAt(0) != '[') | |
Wladimir Palant
2013/04/03 12:42:19
I think you can assume that the filter engine will
| |
824 { | |
825 int filterType = 0; | |
1211 | 826 |
1212 //Rename old filter file if exists | 827 // We need to categorize the filters |
1213 if (filename == PERSONAL_FILTER_FILE) | 828 // We have three options, whitelist, block or element hiding |
1214 { | 829 // See http://adblockplus.org/en/filters for further documentation |
1215 HANDLE hFile = ::CreateFile(m_dataPath + PERSONAL_FILTER_FILE_OLD, GENERIC _READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); | |
1216 if (hFile != INVALID_HANDLE_VALUE) | |
1217 { | |
1218 CloseHandle(hFile); | |
1219 int res = _wrename(m_dataPath + PERSONAL_FILTER_FILE_OLD, m_dataPath + f ilename); | |
1220 DWORD err = GetLastError(); | |
1221 err = 0; | |
1222 } | |
1223 } | |
1224 | 830 |
1225 // Read file | 831 // @@ indicates white listing rule |
1226 HANDLE hFile = ::CreateFile(m_dataPath + filename, GENERIC_READ, 0, NULL, OP EN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); | 832 if (filter.Find(L"@@") == 0) |
1227 if (hFile == INVALID_HANDLE_VALUE) | |
1228 { | |
1229 DWORD dwError = ::GetLastError(); | |
1230 #ifdef PRODUCT_ADBLOCKPLUS | |
1231 // File not found - request another download! | |
1232 if (dwError == ERROR_FILE_NOT_FOUND) | |
1233 { | |
1234 if (!downloadPath.IsEmpty()) | |
1235 { | 833 { |
1236 client->RequestFilterDownload(filename, downloadPath); | 834 filterType = CFilter::filterTypeWhiteList; |
835 | |
836 filter.Delete(0, 2); | |
1237 } | 837 } |
1238 else if (filename == PERSONAL_FILTER_FILE) | 838 // If a filter contains ## then it is a element hiding rule |
839 else if (filter.Find(L"#") >= 0) | |
1239 { | 840 { |
1240 // Open new file | 841 filterType = CFilter::filterTypeElementHide; |
1241 HANDLE hPersonalFile = ::CreateFile(CPluginSettings::GetDataPath(PERSO NAL_FILTER_FILE), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); | 842 } |
1242 if (hPersonalFile) | 843 //Anything we do not support here |
1243 { | 844 else if (filter.Find(L"*") == 0) |
1244 // Build filter string | 845 { |
1245 CStringA line; | 846 filterType = CFilter::filterTypeUnknown; |
847 } | |
848 // Else, it is a general rule | |
849 else | |
850 { | |
851 filterType = CFilter::filterTypeBlocking; | |
852 } | |
1246 | 853 |
1247 line += "[Adblock Plus - personal filters]\r\n"; | 854 try |
1248 line += "!\r\n"; | 855 { |
1249 line += "! In this file you can enter your own filters.\r\n"; | 856 if (filterType == CFilter::filterTypeElementHide) |
1250 line += "! Any updates to this file\r\n"; | 857 { |
1251 line += "! will take effect the next time a new tab or window is ope ned in\r\n"; | 858 AddFilterElementHide(filter); |
1252 line += "! Internet Explorer.\r\n"; | |
1253 line += "!\r\n"; | |
1254 line += "! To define filters you should use the adblockplus format, described on:\r\n"; | |
1255 line += "! http://adblockplus.org/en/filters\r\n"; | |
1256 line += "!\r\n"; | |
1257 line += "! File encoding: ANSI\r\n"; | |
1258 line += "!\r\n"; | |
1259 line += "!-------------------------Ad blocking rules---------------- ----------!\r\n"; | |
1260 | |
1261 // Write file | |
1262 DWORD dwBytesWritten = 0; | |
1263 ::WriteFile(hPersonalFile, line.GetBuffer(), line.GetLength(), &dwBy tesWritten, NULL); | |
1264 | |
1265 // Close file | |
1266 ::CloseHandle(hPersonalFile); | |
1267 } | 859 } |
1268 } | 860 } |
1269 } | 861 catch(...) |
1270 else | |
1271 #endif | |
1272 { | |
1273 DEBUG_ERROR_LOG(dwError, PLUGIN_ERROR_FILTER, PLUGIN_ERROR_FILTER_READ_F ILE, "Filter::ParseFilters - Open file:" + filename) | |
1274 } | |
1275 } | |
1276 else | |
1277 { | |
1278 // Read file | |
1279 char buffer[8193]; | |
1280 LPVOID pBuffer = buffer; | |
1281 LPBYTE pByteBuffer = (LPBYTE)pBuffer; | |
1282 DWORD dwBytesRead = 0; | |
1283 BOOL bRead = TRUE; | |
1284 | |
1285 //Init MLang | |
1286 CoInitialize(NULL); | |
1287 HRESULT hr = S_OK; | |
1288 CComPtr<IMultiLanguage2> pMultiLanguage; | |
1289 hr = CoCreateInstance(CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER, II D_IMultiLanguage2, (void**)&pMultiLanguage); | |
1290 | |
1291 | |
1292 bool codepageAvailable = false; | |
1293 DetectEncodingInfo encodingInfos[10]; | |
1294 int scores = 10; | |
1295 while ((bRead = ::ReadFile(hFile, pBuffer, 8192, &dwBytesRead, NULL)) == T RUE && dwBytesRead > 0) | |
1296 { | |
1297 //detect codepage based on first buffer | |
1298 if (!codepageAvailable) | |
1299 { | 862 { |
1300 unsigned int srcLength = fileContent.GetLength(); | 863 //just ignore all errors we might get when adding filters |
Felix Dahlke
2013/04/03 05:35:27
We should probably at least log exceptions.
| |
1301 char* buf = (char*)fileContent.GetBufferSetLength(fileContent.GetLengt h()); | |
1302 hr = pMultiLanguage->DetectInputCodepage(0, 0, (char*)pBuffer, (int*)& dwBytesRead, encodingInfos, &scores); | |
1303 codepageAvailable = true; | |
1304 } | |
1305 | |
1306 | |
1307 | |
1308 //Unicode | |
1309 if ((encodingInfos[0].nCodePage == 1200) || (encodingInfos[0].nCodePage == 1201)) | |
1310 { | |
1311 fileContent += CString((wchar_t*)buffer, dwBytesRead / 2); | |
1312 } | |
1313 else | |
1314 { | |
1315 pByteBuffer[dwBytesRead] = 0; | |
1316 fileContent += buffer; | |
1317 } | |
1318 } | |
1319 | |
1320 //Remove the BOM for UTF-8 | |
1321 if (((BYTE)fileContent.GetAt(0) == 0x3F) && ((BYTE)fileContent.GetAt(1) == 0xBB) && ((BYTE)fileContent.GetAt(2) == 0x57)) | |
1322 { | |
1323 fileContent.Delete(0, 3); | |
1324 } | |
1325 // Read error | |
1326 if (!bRead) | |
1327 { | |
1328 DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_FILTER, PLUGIN_ERROR_FILT ER_READ_FILE, "Filter::ParseFilters - Read") | |
1329 } | |
1330 else | |
1331 { | |
1332 isRead = true; | |
1333 | |
1334 UINT dstSize = 0; | |
1335 BYTE* buf = (BYTE*)fileContent.GetString(); | |
1336 UINT srcLength = fileContent.GetLength(); | |
1337 if (((encodingInfos[scores - 1].nCodePage) == 1200) || ((encodingInfos[s cores - 1].nCodePage) == 1201)) | |
1338 { | |
1339 srcLength = srcLength * 2; | |
1340 } | |
1341 hr = pMultiLanguage->ConvertString(NULL, encodingInfos[scores - 1].nCode Page, 1252, (BYTE*)buf, &srcLength, NULL, &dstSize); | |
1342 char* bufferTmp = new char[dstSize + 1]; | |
1343 hr = pMultiLanguage->ConvertString(NULL, encodingInfos[scores - 1].nCode Page, 1252, (BYTE*)buf, &srcLength, (BYTE*)bufferTmp, &dstSize); | |
1344 bufferTmp[dstSize] = 0; | |
1345 //Unicode | |
1346 if ((encodingInfos[0].nCodePage == 1200) || (encodingInfos[0].nCodePage == 1201)) | |
1347 { | |
1348 //remove BOM for Unicode | |
1349 fileContent = (char*)bufferTmp; | |
1350 fileContent.Delete(0, 1); | |
1351 | |
1352 } | |
1353 else | |
1354 { | |
1355 wchar_t* fileContentBuffer = fileContent.GetBufferSetLength(dstSize); | |
1356 memset(fileContentBuffer, 0, dstSize); | |
1357 memcpy(fileContentBuffer, bufferTmp, dstSize); | |
1358 } | |
1359 delete [] bufferTmp; | |
1360 | |
1361 } | |
1362 | |
1363 // Close file | |
1364 ::CloseHandle(hFile); | |
1365 } | |
1366 | |
1367 #ifdef PRODUCT_ADBLOCKPLUS | |
1368 } | |
1369 #endif | |
1370 if (isRead) | |
1371 { | |
1372 // Parse file string | |
1373 int pos = 0; | |
1374 CString filter = fileContent.Tokenize(L"\n\r", pos); | |
1375 | |
1376 s_criticalSectionFilterMap.Lock(); | |
1377 { | |
1378 while (pos >= 0) | |
1379 { | |
1380 // If the line is not commented out | |
1381 if (!filter.Trim().IsEmpty() && filter.GetAt(0) != '!' && filter.GetAt(0 ) != '[') | |
1382 { | |
1383 int filterType = 0; | |
1384 | |
1385 // We need to categorize the filters | |
1386 // We have three options, whitelist, block or element hiding | |
1387 // See http://adblockplus.org/en/filters for further documentation | |
1388 | |
1389 // @@ indicates white listing rule | |
1390 if (filter.Find(L"@@") == 0) | |
1391 { | |
1392 filterType = CFilter::filterTypeWhiteList; | |
1393 | |
1394 filter.Delete(0, 2); | |
1395 } | |
1396 // If a filter contains ## then it is a element hiding rule | |
1397 else if (filter.Find(L"#") >= 0) | |
1398 { | |
1399 filterType = CFilter::filterTypeElementHide; | |
1400 } | |
1401 //Anything we do not support here | |
1402 else if (filter.Find(L"*") == 0) | |
1403 { | |
1404 filterType = CFilter::filterTypeUnknown; | |
1405 } | |
1406 // Else, it is a general rule | |
1407 else | |
1408 { | |
1409 filterType = CFilter::filterTypeBlocking; | |
1410 } | |
1411 | |
1412 try | |
1413 { | |
1414 // Element hiding not supported yet | |
1415 if (filterType == CFilter::filterTypeElementHide) | |
1416 { | |
1417 AddFilterElementHide(filter, filename); | |
1418 } | |
1419 else if (filterType != CFilter::filterTypeUnknown) | |
1420 { | |
1421 AddFilter(filter, filename, filterType); | |
1422 } | |
1423 } | |
1424 catch(...) | |
1425 { | |
1426 //just ignore all errors we might get when adding filters | |
1427 } | |
1428 } | |
1429 | |
1430 CString tmp = L""; | |
1431 tmp.Format(L"Current %d, Total %d", pos, fileContent.GetLength()); | |
1432 filter = fileContent.Tokenize(L"\n\r", pos); | |
1433 int nextPos = fileContent.Find(L"\n", pos + 1); | |
1434 if (nextPos < 0) | |
1435 { | |
1436 filter = ""; | |
1437 pos = -1; | |
1438 | |
1439 } | |
1440 if ((filter.GetLength() > 5000) || (fileContent.GetLength() - 5 <= pos)) | |
1441 { | |
1442 filter = ""; | |
1443 } | 864 } |
1444 } | 865 } |
1445 } | 866 } |
1446 s_criticalSectionFilterMap.Unlock(); | 867 } |
1447 } | 868 s_criticalSectionFilterMap.Unlock(); |
1448 | 869 |
1449 return isRead; | 870 return isRead; |
1450 } | 871 } |
1451 | 872 |
1452 void CPluginFilter::ParseFilters(const TFilterFileList& list) | 873 void CPluginFilter::ClearFilters() |
1453 { | 874 { |
1454 // Clear filter maps | 875 // Clear filter maps |
1455 s_criticalSectionFilterMap.Lock(); | 876 s_criticalSectionFilterMap.Lock(); |
1456 { | 877 { |
1457 for (int i = 0; i < 2; i++) | 878 for (int i = 0; i < 2; i++) |
1458 { | 879 { |
1459 for (int j = 0; j < 2; j++) | 880 for (int j = 0; j < 2; j++) |
1460 { | 881 { |
1461 m_filterMap[i][j].clear(); | 882 m_filterMap[i][j].clear(); |
1462 } | 883 } |
1463 m_filterMapDefault[i].clear(); | 884 m_filterMapDefault[i].clear(); |
1464 } | 885 } |
1465 | 886 |
1466 m_elementHideTags.clear(); | 887 m_elementHideTags.clear(); |
1467 m_elementHideTagsId.clear(); | 888 m_elementHideTagsId.clear(); |
1468 m_elementHideTagsClass.clear(); | 889 m_elementHideTagsClass.clear(); |
1469 m_elementHideDomains.clear(); | 890 m_elementHideDomains.clear(); |
1470 } | 891 } |
1471 s_criticalSectionFilterMap.Unlock(); | 892 s_criticalSectionFilterMap.Unlock(); |
1472 | |
1473 // Load the files | |
1474 #ifdef PRODUCT_ADBLOCKPLUS | |
1475 CPluginClient* client = CPluginClient::GetInstance(); | |
1476 #endif | |
1477 for (TFilterFileList::const_iterator it = list.begin(); it != list.end(); ++it ) | |
1478 { | |
1479 ReadFilter(it->first, it->second); | |
1480 } | |
1481 | |
1482 #ifdef PERSONAL_FILTER_FILE | |
1483 ReadFilter(PERSONAL_FILTER_FILE); | |
1484 #endif | |
1485 | |
1486 #ifdef ENABLE_DEBUG_SELFTEST | |
1487 CStringA sCount; | |
1488 s_criticalSectionFilterMap.Lock(); | |
1489 { | |
1490 sCount.Format("Block:%d/%d - BlockDef:%d - White:%d - WhiteDef:%d - Hide:%d/ %d", m_filterMap[0][0].size(), m_filterMap[0][1].size(), m_filterMapDefault[0].s ize(), m_filterMap[1][0].size(), m_filterMapDefault[1].size(), m_elementHideTags .size() + m_elementHideTagsClass.size() + m_elementHideTagsId.size(), m_elementH ideDomains.size()); | |
1491 } | |
1492 s_criticalSectionFilterMap.Unlock(); | |
1493 DEBUG_GENERAL("*** Filter count:" + sCount); | |
1494 #endif | |
1495 } | 893 } |
1496 | 894 |
1497 | 895 |
1498 bool CPluginFilter::IsMatchFilter(const CFilter& filter, CString src, const CStr ing& srcDomain, const CString& domain) const | 896 bool CPluginFilter::IsMatchFilter(const CFilter& filter, CString src, const CStr ing& srcDomain, const CString& domain) const |
1499 { | 897 { |
1500 // Initial checks | 898 // Initial checks |
1501 | 899 |
1502 // $match_case | 900 // $match_case |
1503 if (!filter.m_isMatchCase) | 901 if (!filter.m_isMatchCase) |
1504 { | 902 { |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1793 { | 1191 { |
1794 type = "???"; | 1192 type = "???"; |
1795 | 1193 |
1796 std::map<int,CString>::const_iterator it = m_contentMapText.find(contentType ); | 1194 std::map<int,CString>::const_iterator it = m_contentMapText.find(contentType ); |
1797 if (it != m_contentMapText.end()) | 1195 if (it != m_contentMapText.end()) |
1798 { | 1196 { |
1799 type = it->second; | 1197 type = it->second; |
1800 } | 1198 } |
1801 } | 1199 } |
1802 | 1200 |
1201 CPluginClient* client = CPluginClient::GetInstance(); | |
1202 AdblockPlus::FilterEngine* filterEngine = client->GetFilterEngine(); | |
1203 | |
1204 src.OemToCharA(); | |
Wladimir Palant
2013/04/03 12:42:19
Are we really getting all URLs as ASCII? What abou
Felix Dahlke
2013/04/03 12:51:04
The problem is that ABP for IE uses UTF-16 interna
Oleksandr
2013/04/03 13:12:17
I've used CT2CA in the end (not included in this p
| |
1205 | |
1206 std::string contentTypeString = ""; | |
Wladimir Palant
2013/04/03 12:42:19
This needs a TODO comment: "Need to guess the cont
| |
1207 | |
1208 std::string url = (char*)src.GetBuffer(); | |
Felix Dahlke
2013/04/03 05:35:27
I'm really leaving my comfort zone here, but some
| |
1209 if (filterEngine->Matches(url, contentTypeString)) | |
1210 { | |
1211 if (addDebug) | |
1212 { | |
1213 DEBUG_FILTER("Filter::ShouldBlock " + type + " YES") | |
1214 | |
1215 #ifdef ENABLE_DEBUG_RESULT | |
1216 CPluginDebug::DebugResultBlocking(type, src); | |
1217 #endif | |
1218 } | |
1219 return true; | |
1220 } | |
1803 const CFilter* blockFilter = MatchFilter(CFilter::filterTypeBlocking, src, con tentType, domain); | 1221 const CFilter* blockFilter = MatchFilter(CFilter::filterTypeBlocking, src, con tentType, domain); |
1804 if (blockFilter) | 1222 if (blockFilter) |
1805 { | 1223 { |
1806 const CFilter* whiteFilter = MatchFilter(CFilter::filterTypeWhiteList, src, contentType, domain); | 1224 const CFilter* whiteFilter = MatchFilter(CFilter::filterTypeWhiteList, src, contentType, domain); |
1807 if (whiteFilter) | 1225 if (whiteFilter) |
1808 { | 1226 { |
1809 if (addDebug) | 1227 if (addDebug) |
1810 { | 1228 { |
1811 DEBUG_FILTER("Filter::ShouldBlock " + type + " NO src:" + src + " - whi telist:\"" + whiteFilter->m_filterText + "\""); | 1229 DEBUG_FILTER("Filter::ShouldBlock " + type + " NO src:" + src + " - whi telist:\"" + whiteFilter->m_filterText + "\""); |
1812 } | 1230 } |
1813 blockFilter = NULL; | 1231 blockFilter = NULL; |
1814 } | 1232 } |
1815 else if (addDebug) | 1233 else if (addDebug) |
1816 { | 1234 { |
1817 DEBUG_FILTER("Filter::ShouldBlock " + type + " YES src:" + src + " - \"" + blockFilter->m_filterText + "\"") | 1235 DEBUG_FILTER("Filter::ShouldBlock " + type + " YES src:" + src + " - \"" + blockFilter->m_filterText + "\"") |
1818 | 1236 |
1819 #ifdef ENABLE_DEBUG_RESULT | 1237 #ifdef ENABLE_DEBUG_RESULT |
1820 CPluginDebug::DebugResultBlocking(type, src, blockFilter->m_filterText, blockFilter->m_filterFile); | 1238 CPluginDebug::DebugResultBlocking(type, src); |
1821 #endif | 1239 #endif |
1822 } | 1240 } |
1823 } | 1241 } |
1824 else if (addDebug) | 1242 else if (addDebug) |
1825 { | 1243 { |
1826 DEBUG_FILTER("Filter::ShouldBlock " + type + " NO src:" + src) | 1244 DEBUG_FILTER("Filter::ShouldBlock " + type + " NO src:" + src) |
1827 } | 1245 } |
1828 | 1246 |
1829 return blockFilter ? true : false; | 1247 return blockFilter ? true : false; |
1830 } | 1248 } |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1973 if (pos > 0 && domain.GetLength() + pos == subdomain.GetLength()) | 1391 if (pos > 0 && domain.GetLength() + pos == subdomain.GetLength()) |
1974 { | 1392 { |
1975 if (subdomain.GetAt(pos - 1) == '.') | 1393 if (subdomain.GetAt(pos - 1) == '.') |
1976 { | 1394 { |
1977 return true; | 1395 return true; |
1978 } | 1396 } |
1979 } | 1397 } |
1980 | 1398 |
1981 return false; | 1399 return false; |
1982 } | 1400 } |
1983 | |
1984 #ifdef PRODUCT_ADBLOCKPLUS | |
1985 | |
1986 void CPluginFilter::CreateFilters() | |
1987 { | |
1988 CPluginFilterLock lock("filter1.txt"); | |
1989 if (lock.IsLocked()) | |
1990 { | |
1991 // Check file existence | |
1992 std::ifstream is; | |
1993 is.open(CPluginSettings::GetDataPath("filter1.txt"), std::ios_base::in); | |
1994 if (is.is_open()) | |
1995 { | |
1996 is.close(); | |
1997 return; | |
1998 } | |
1999 | |
2000 // Open file | |
2001 HANDLE hFile = ::CreateFile(CPluginSettings::GetDataPath("filter1.txt"), GEN ERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); | |
2002 if (hFile == INVALID_HANDLE_VALUE) | |
2003 { | |
2004 DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_FILTER, PLUGIN_ERROR_FILTER _CREATE_FILE_OPEN, "Filter::Create - CreateFile"); | |
2005 } | |
2006 else | |
2007 { | |
2008 // Build filter string | |
2009 CStringA line; | |
2010 line += "[Adblock Plus 1.1]\r\n"; | |
2011 line += "! Checksum: 0xN4e5SegJGeZuYZQGhShQ\r\n"; | |
2012 line += "! EasyList - https://easylist.adblockplus.org/\r\n"; | |
2013 line += "! Last modified: 4 Nov 2010 16:30 UTC\r\n"; | |
2014 line += "! Expires: 5 days (update frequency)\r\n"; | |
2015 line += "! Licence: https://easylist-downloads.adblockplus.org/COPYING\r\n "; | |
2016 line += "!\r\n"; | |
2017 line += "! Please report any unblocked adverts or problems\r\n"; | |
2018 line += "! in the forums (http://forums.lanik.us/)\r\n"; | |
2019 line += "! or via e-mail (easylist.subscription@gmail.com).\r\n"; | |
2020 line += "!\r\n"; | |
2021 line += "!-----------------General advert blocking filters---------------- -!\r\n"; | |
2022 | |
2023 | |
2024 // Write file | |
2025 DWORD dwBytesWritten = 0; | |
2026 if (::WriteFile(hFile, line.GetBuffer(), line.GetLength(), &dwBytesWritten , NULL) && dwBytesWritten == line.GetLength()) | |
2027 { | |
2028 // Set correct version | |
2029 CPluginSettings* settings = CPluginSettings::GetInstance(); | |
2030 | |
2031 settings->AddFilterUrl(CString(FILTERS_PROTOCOL) + CString(FILTERS_HOST) + "/easylist.txt", 1); | |
2032 settings->AddFilterFileName(CString(FILTERS_PROTOCOL) + CString(FILTERS_ HOST) + "/easylist.txt", "filter1.txt"); | |
2033 settings->Write(); | |
2034 } | |
2035 else | |
2036 { | |
2037 DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_FILTER, PLUGIN_ERROR_FILT ER_CREATE_FILE_WRITE, "Filter::Create - WriteFile"); | |
2038 } | |
2039 | |
2040 // Close file | |
2041 if (!::CloseHandle(hFile)) | |
2042 { | |
2043 DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_FILTER, PLUGIN_ERROR_FILT ER_CREATE_FILE_CLOSE, "Filter::Create - CloseHandle"); | |
2044 } | |
2045 } | |
2046 } | |
2047 } | |
2048 | |
2049 #endif // PRODUCT_ADBLOCKPLUS | |
2050 | |
2051 | |
2052 #ifdef PRODUCT_ADBLOCKPLUS | |
2053 | |
2054 bool CPluginFilter::IsAlive() const | |
2055 { | |
2056 bool isAlive; | |
2057 | |
2058 s_criticalSectionFilterMap.Lock(); | |
2059 { | |
2060 isAlive = !m_filterMap[0][0].empty(); | |
2061 } | |
2062 s_criticalSectionFilterMap.Unlock(); | |
2063 | |
2064 return isAlive; | |
2065 } | |
2066 | |
2067 #endif | |
OLD | NEW |