| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 /* | 
|  | 2  * This file is part of Adblock Plus <https://adblockplus.org/>, | 
|  | 3  * Copyright (C) 2006-present eyeo GmbH | 
|  | 4  * | 
|  | 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 | 
|  | 7  * published by the Free Software Foundation. | 
|  | 8  * | 
|  | 9  * Adblock Plus is distributed in the hope that it will be useful, | 
|  | 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | 12  * GNU General Public License for more details. | 
|  | 13  * | 
|  | 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/>. | 
|  | 16  */ | 
|  | 17 | 
|  | 18 #include "ElemHide.h" | 
|  | 19 | 
|  | 20 DependentString _ElemHide_SelectorList::SelectorAt(size_t idx) const | 
|  | 21 { | 
|  | 22   return DependentString(mSelectors[idx]->GetSelector()); | 
|  | 23 } | 
|  | 24 | 
|  | 25 const String& _ElemHide_SelectorList::FilterKeyAt(size_t idx) const | 
|  | 26 { | 
|  | 27   return mSelectors[idx]->GetText(); | 
|  | 28 } | 
|  | 29 | 
|  | 30 ElemHide* ElemHide::mInstance = new ElemHide(); | 
|  | 31 | 
|  | 32 void ElemHide::Clear() | 
|  | 33 { | 
|  | 34   mFilters.clear(); | 
|  | 35   mExceptions.clear(); | 
|  | 36   mFiltersByDomain.clear(); | 
|  | 37   mKnownExceptions.clear(); | 
|  | 38 } | 
|  | 39 | 
|  | 40 namespace { | 
|  | 41 | 
|  | 42   ActiveFilter::DomainMap* DefaultDomains() | 
|  | 43   { | 
|  | 44     static ActiveFilter::DomainMap defaultDomains; | 
|  | 45     if (defaultDomains.empty()) | 
|  | 46       defaultDomains[u""_str] = true; | 
|  | 47     return &defaultDomains; | 
|  | 48   } | 
|  | 49 | 
|  | 50 } | 
|  | 51 | 
|  | 52 void ElemHide::AddToFiltersByDomain(ElemHideBase& filter) | 
|  | 53 { | 
|  | 54   auto domains = filter.GetDomains(); | 
|  | 55   if (!domains) | 
|  | 56     domains = DefaultDomains(); | 
|  | 57 | 
|  | 58   DependentString text(filter.GetText()); | 
|  | 59   for (auto& domain : *domains) | 
|  | 60   { | 
|  | 61     auto& filters = mFiltersByDomain[domain.first]; | 
|  | 62     if (domain.second) | 
|  | 63       filters[text] = ElemHideBasePtr(&filter); | 
|  | 64     else | 
|  | 65     { | 
|  | 66       auto iter = filters.find(text); | 
|  | 67       if (iter != filters.end()) | 
|  | 68         filters.erase(iter); | 
|  | 69     } | 
|  | 70   } | 
|  | 71 } | 
|  | 72 | 
|  | 73 void ElemHide::Add(ElemHideBase& filter) | 
|  | 74 { | 
|  | 75   // we must ensure we have the right class. | 
|  | 76   // This is an error, but we might get Invalid filters. | 
|  | 77   if (!filter.As<ElemHideBase>()) | 
|  | 78     return; | 
|  | 79 | 
|  | 80   DependentString text(filter.GetText()); | 
|  | 81   if (filter.mType == Filter::Type::ELEMHIDEEXCEPTION) | 
|  | 82   { | 
|  | 83     if (mKnownExceptions.find(text)) | 
|  | 84       return; | 
|  | 85 | 
|  | 86     auto selector = filter.GetSelector(); | 
|  | 87     mExceptions[selector].push_back( | 
|  | 88       ElemHideExceptionPtr(filter.As<ElemHideException>())); | 
|  | 89 | 
|  | 90     // Selector is not longer unconditional | 
|  | 91     mUnconditionalSelectors.erase(text); | 
|  | 92     mUnconditionalSelectorsCache.reset(); | 
|  | 93     mKnownExceptions.insert(text); | 
|  | 94   } | 
|  | 95   else | 
|  | 96   { | 
|  | 97     if (mFilters.find(text)) | 
|  | 98       return; | 
|  | 99 | 
|  | 100     mFilters[text] = ElemHideBasePtr(filter.As<ElemHideBase>()); | 
|  | 101     if (!((filter.GetDomains() && filter.GetDomains()->size()) || | 
|  | 102           mExceptions.find(filter.GetSelector()))) | 
|  | 103     { | 
|  | 104       // The new filter's selector is unconditionally applied to all domains | 
|  | 105       mUnconditionalSelectors.insert(text); | 
|  | 106       mUnconditionalSelectorsCache.reset(); | 
|  | 107     } | 
|  | 108     else | 
|  | 109     { | 
|  | 110       AddToFiltersByDomain(filter); | 
|  | 111     } | 
|  | 112   } | 
|  | 113 } | 
|  | 114 | 
|  | 115 void ElemHide::Remove(ElemHideBase& filter) | 
|  | 116 { | 
|  | 117   DependentString text(filter.GetText()); | 
|  | 118 | 
|  | 119   if (filter.mType == Filter::Type::ELEMHIDEEXCEPTION) | 
|  | 120   { | 
|  | 121     // never seen the exception. | 
|  | 122     if (!mKnownExceptions.find(text)) | 
|  | 123       return; | 
|  | 124 | 
|  | 125     auto selector = filter.GetSelector(); | 
|  | 126     auto& list = mExceptions[selector]; | 
|  | 127     auto iter = std::find( | 
|  | 128       list.begin(), list.end(), | 
|  | 129       ElemHideExceptionPtr(filter.As<ElemHideException>())); | 
|  | 130     if (iter != list.end()) | 
|  | 131       list.erase(iter); | 
|  | 132     mKnownExceptions.erase(text); | 
|  | 133   } | 
|  | 134   else | 
|  | 135   { | 
|  | 136     if (!mFilters.find(text)) | 
|  | 137       return; | 
|  | 138 | 
|  | 139     if (mUnconditionalSelectors.find(text)) | 
|  | 140     { | 
|  | 141       mUnconditionalSelectors.erase(text); | 
|  | 142       mUnconditionalSelectorsCache.reset(); | 
|  | 143     } | 
|  | 144     else | 
|  | 145     { | 
|  | 146       auto domains = filter.GetDomains(); | 
|  | 147       for (auto domain : *domains) | 
|  | 148       { | 
|  | 149         auto& list = mFiltersByDomain[domain.first]; | 
|  | 150         list.erase(text); | 
|  | 151       } | 
|  | 152     } | 
|  | 153 | 
|  | 154     mFilters.erase(text); | 
|  | 155   } | 
|  | 156 } | 
|  | 157 | 
|  | 158 ElemHideException* ElemHide::GetException(const ElemHideBase& filter, | 
|  | 159                                           DependentString& docDomain) const | 
|  | 160 { | 
|  | 161   auto exception = mExceptions.find(filter.GetSelector()); | 
|  | 162   if (!exception) | 
|  | 163     return nullptr; | 
|  | 164 | 
|  | 165   auto& list = exception->second; | 
|  | 166   for (auto iter = list.rbegin(); iter != list.rend(); iter++) | 
|  | 167   { | 
|  | 168     DependentString domain(docDomain); | 
|  | 169     if ((*iter)->IsActiveOnDomain(domain, u""_str)) | 
|  | 170     { | 
|  | 171       ElemHideExceptionPtr filter(*iter); | 
|  | 172       return filter.release(); | 
|  | 173     } | 
|  | 174   } | 
|  | 175 | 
|  | 176   return nullptr; | 
|  | 177 } | 
|  | 178 | 
|  | 179 _ElemHide_SelectorList* ElemHide::GetUnconditionalSelectors() const | 
|  | 180 { | 
|  | 181   if (!mUnconditionalSelectorsCache) | 
|  | 182   { | 
|  | 183     mUnconditionalSelectorsCache = intrusive_ptr<_ElemHide_SelectorList>(new _El
     emHide_SelectorList, false); | 
|  | 184     annotate_address(mUnconditionalSelectorsCache.get(), "_ElemHide_SelectorList
     "); | 
|  | 185     for (auto unconditional : mUnconditionalSelectors) | 
|  | 186     { | 
|  | 187       auto filter = mFilters.find(unconditional.first); | 
|  | 188       if (filter) | 
|  | 189         mUnconditionalSelectorsCache->push_back(filter->second); | 
|  | 190     } | 
|  | 191   } | 
|  | 192   return mUnconditionalSelectorsCache.get(); | 
|  | 193 } | 
|  | 194 | 
|  | 195 _ElemHide_SelectorList* ElemHide::GetSelectorsForDomain(const String& domain, | 
|  | 196   Criteria criteria) const | 
|  | 197 { | 
|  | 198   _ElemHide_SelectorList* selectors = new _ElemHide_SelectorList; | 
|  | 199   annotate_address(selectors, "_ElemHide_SelectorList"); | 
|  | 200 | 
|  | 201   if (criteria < NO_UNCONDITIONAL) | 
|  | 202     selectors->append(GetUnconditionalSelectors()); | 
|  | 203 | 
|  | 204   bool specificOnly = (criteria >= SPECIFIC_ONLY); | 
|  | 205   StringSet seenFilters; | 
|  | 206   DependentString docDomain(domain); | 
|  | 207 | 
|  | 208   DependentString currentDomain(domain); | 
|  | 209   while (true) | 
|  | 210   { | 
|  | 211     if (specificOnly && currentDomain.empty()) | 
|  | 212       break; | 
|  | 213 | 
|  | 214     auto filters = mFiltersByDomain.find(currentDomain); | 
|  | 215     if (filters) | 
|  | 216     { | 
|  | 217       for (auto& entry : filters->second) | 
|  | 218       { | 
|  | 219         if (entry.first.is_invalid()) | 
|  | 220           continue; | 
|  | 221 | 
|  | 222         if (seenFilters.find(entry.first)) | 
|  | 223           continue; | 
|  | 224         seenFilters.insert(entry.first); | 
|  | 225 | 
|  | 226         auto filter = entry.second; | 
|  | 227         if (filter && !GetException(*filter, docDomain)) | 
|  | 228           selectors->push_back(filter); | 
|  | 229       } | 
|  | 230     } | 
|  | 231 | 
|  | 232     if (currentDomain.empty()) | 
|  | 233       break; | 
|  | 234 | 
|  | 235     auto nextDot = currentDomain.find('.'); | 
|  | 236     currentDomain = nextDot == String::npos ? | 
|  | 237       u""_str : DependentString(currentDomain, nextDot + 1); | 
|  | 238   } | 
|  | 239 | 
|  | 240   return selectors; | 
|  | 241 } | 
| OLD | NEW | 
|---|