| Left: | ||
| Right: |
| 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) | |
|
sergei
2015/11/30 12:37:53
It should be in anonymous namespace.
Eric
2015/11/30 15:54:06
Done.
| |
| 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 |
|
sergei
2015/11/30 12:37:52
It seems to know the current position would be als
sergei
2015/11/30 12:37:52
It's really not clear from the name of the method
sergei
2015/11/30 12:37:53
It should be in anonymous namespace.
Eric
2015/11/30 15:54:05
I changed the function to a subclass of std::runti
Eric
2015/11/30 15:54:05
Done.
Eric
2015/11/30 15:54:06
I thought about doing that. I decided not to since
| |
| 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)); |
|
sergei
2015/11/30 12:37:52
space after comma is missed
Eric
2015/11/30 15:54:06
Done.
| |
| 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])) + "'='"); |
|
sergei
2015/11/30 12:37:52
std::string(1, static_cast<char>(arg[0]))
it seems
Eric
2015/11/30 15:54:06
ToUtf8String only takes wstring arguments. The onl
sergei
2015/11/30 16:36:03
Acknowledged.
| |
| 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)) |
|
sergei
2015/11/30 12:37:53
additional space after '('
| |
| 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; |
|
sergei
2015/11/30 12:37:52
Did we decide to use `wcstok_s` instead of custom
Eric
2015/11/30 15:54:05
We're using that function at present in exactly on
sergei
2015/11/30 16:36:03
Of course it's better than 'wcstok_s', it's diffic
Eric
2015/11/30 17:05:46
FWIW, the standard library function it replaced, t
Oleksandr
2015/12/04 01:03:15
TokenSequence looks beautiful but unnecessary, IMH
Eric
2015/12/06 17:39:56
No one ever needs beautiful code. It does, however
| |
| 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) |
|
sergei
2015/11/30 12:37:52
additional space after `++`
Eric
2015/11/30 15:54:07
Done.
| |
| 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 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 503 | 511 |
| 504 return true; | 512 return true; |
| 505 } | 513 } |
| 506 | 514 |
| 507 bool CPluginFilter::IsElementHidden(const std::wstring& tag, IHTMLElement* pEl, const std::wstring& domain, const std::wstring& indent) const | 515 bool CPluginFilter::IsElementHidden(const std::wstring& tag, IHTMLElement* pEl, const std::wstring& domain, const std::wstring& indent) const |
| 508 { | 516 { |
| 509 std::wstring id; | 517 std::wstring id; |
| 510 CComBSTR idBstr; | 518 CComBSTR idBstr; |
| 511 if (SUCCEEDED(pEl->get_id(&idBstr)) && idBstr) | 519 if (SUCCEEDED(pEl->get_id(&idBstr)) && idBstr) |
| 512 { | 520 { |
| 513 id = std::wstring(ToWstring(idBstr)); | 521 id = ToWstring(idBstr); |
|
sergei
2015/11/30 12:37:52
It should be just `id = ToWstring(idBstr);`
Eric
2015/11/30 15:54:05
Done.
Good catch. That's leftover code from an ea
| |
| 514 } | 522 } |
| 515 std::wstring classNames; | 523 std::wstring classNames; |
| 516 CComBSTR classNamesBstr; | 524 CComBSTR classNamesBstr; |
| 517 if (SUCCEEDED(pEl->get_className(&classNamesBstr)) && classNamesBstr) | 525 if (SUCCEEDED(pEl->get_className(&classNamesBstr)) && classNamesBstr) |
| 518 { | 526 { |
| 519 classNames = ToWstring(classNamesBstr); | 527 classNames = ToWstring(classNamesBstr); |
| 520 } | 528 } |
| 521 | 529 |
| 522 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 530 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); |
| 523 { | 531 { |
| 524 // Search tag/id filters | 532 // Search tag/id filters |
| 525 if (!id.empty()) | 533 if (!id.empty()) |
| 526 { | 534 { |
| 527 auto idItEnum = m_elementHideTagsId.equal_range(std::make_pair(tag, id)); | 535 auto idItEnum = m_elementHideTagsId.equal_range(std::make_pair(tag, id)); |
| 528 for (auto idIt = idItEnum.first; idIt != idItEnum.second; idIt ++) | 536 for (auto idIt = idItEnum.first; idIt != idItEnum.second; ++idIt) |
|
sergei
2015/11/30 12:37:53
Good chance to change `idIt ++` to `++idIt`.
Eric
2015/11/30 15:54:06
Done.
| |
| 529 { | 537 { |
| 530 if (idIt->second.IsMatchFilterElementHide(pEl)) | 538 if (idIt->second.IsMatchFilterElementHide(pEl)) |
| 531 { | 539 { |
| 532 #ifdef ENABLE_DEBUG_RESULT | 540 #ifdef ENABLE_DEBUG_RESULT |
| 533 DEBUG_HIDE_EL(indent + L"HideEl::Found (tag/id) filter:" + idIt->secon d.m_filterText); | 541 DEBUG_HIDE_EL(indent + L"HideEl::Found (tag/id) filter:" + idIt->secon d.m_filterText); |
| 534 CPluginDebug::DebugResultHiding(tag, L"id:" + id, idIt->second.m_filte rText); | 542 CPluginDebug::DebugResultHiding(tag, L"id:" + id, idIt->second.m_filte rText); |
| 535 #endif | 543 #endif |
| 536 return true; | 544 return true; |
| 537 } | 545 } |
| 538 } | 546 } |
| 539 | 547 |
| 540 // Search general id | 548 // Search general id |
| 541 idItEnum = m_elementHideTagsId.equal_range(std::make_pair(L"", id)); | 549 idItEnum = m_elementHideTagsId.equal_range(std::make_pair(L"", id)); |
| 542 for (auto idIt = idItEnum.first; idIt != idItEnum.second; idIt ++) | 550 for (auto idIt = idItEnum.first; idIt != idItEnum.second; ++idIt) |
|
sergei
2015/11/30 12:37:51
Good chance to change `idIt ++` to `++idIt`
Eric
2015/11/30 15:54:06
Done.
| |
| 543 { | 551 { |
| 544 if (idIt->second.IsMatchFilterElementHide(pEl)) | 552 if (idIt->second.IsMatchFilterElementHide(pEl)) |
| 545 { | 553 { |
| 546 #ifdef ENABLE_DEBUG_RESULT | 554 #ifdef ENABLE_DEBUG_RESULT |
| 547 DEBUG_HIDE_EL(indent + L"HideEl::Found (?/id) filter:" + idIt->second. m_filterText); | 555 DEBUG_HIDE_EL(indent + L"HideEl::Found (?/id) filter:" + idIt->second. m_filterText); |
| 548 CPluginDebug::DebugResultHiding(tag, L"id:" + id, idIt->second.m_filte rText); | 556 CPluginDebug::DebugResultHiding(tag, L"id:" + id, idIt->second.m_filte rText); |
| 549 #endif | 557 #endif |
| 550 return true; | 558 return true; |
| 551 } | 559 } |
| 552 } | 560 } |
| 553 } | 561 } |
| 554 | 562 |
| 555 // Search tag/className filters | 563 // Search tag/className filters |
| 556 if (!classNames.empty()) | 564 if (!classNames.empty()) |
| 557 { | 565 { |
| 558 TokenSequence<std::wstring> ts(classNames, L" \t\n\r"); | 566 wchar_t* nextToken = nullptr; |
|
sergei
2015/11/30 12:37:52
Same here, let's use `wcstok_s` instead of custom
Eric
2015/11/30 15:54:06
See above comment.
| |
| 559 for (auto iterClassName = ts.cbegin(); iterClassName != ts.cend(); ++iterC lassName) | 567 const wchar_t* token = wcstok_s(&classNames[0], L" \t\n\r", &nextToken); |
| 560 { | 568 while (token != nullptr) |
| 561 std::wstring className = *iterClassName; | 569 { |
| 570 std::wstring className(token); | |
| 562 auto classItEnum = m_elementHideTagsClass.equal_range(std::make_pair(tag , className)); | 571 auto classItEnum = m_elementHideTagsClass.equal_range(std::make_pair(tag , className)); |
| 563 for (auto classIt = classItEnum.first; classIt != classItEnum.second; ++ classIt) | 572 for (auto classIt = classItEnum.first; classIt != classItEnum.second; ++ classIt) |
| 564 { | 573 { |
| 565 if (classIt->second.IsMatchFilterElementHide(pEl)) | 574 if (classIt->second.IsMatchFilterElementHide(pEl)) |
| 566 { | 575 { |
| 567 #ifdef ENABLE_DEBUG_RESULT | 576 #ifdef ENABLE_DEBUG_RESULT |
| 568 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); |
| 569 CPluginDebug::DebugResultHiding(tag, L"class:" + className, classIt- >second.m_filterText); | 578 CPluginDebug::DebugResultHiding(tag, L"class:" + className, classIt- >second.m_filterText); |
| 570 #endif | 579 #endif |
| 571 return true; | 580 return true; |
| 572 } | 581 } |
| 573 } | 582 } |
| 574 | 583 |
| 575 // Search general class name | 584 // Search general class name |
| 576 classItEnum = m_elementHideTagsClass.equal_range(std::make_pair(L"", cla ssName)); | 585 classItEnum = m_elementHideTagsClass.equal_range(std::make_pair(L"", cla ssName)); |
| 577 for (auto classIt = classItEnum.first; classIt != classItEnum.second; ++ classIt) | 586 for (auto classIt = classItEnum.first; classIt != classItEnum.second; ++ classIt) |
| 578 { | 587 { |
| 579 if (classIt->second.IsMatchFilterElementHide(pEl)) | 588 if (classIt->second.IsMatchFilterElementHide(pEl)) |
| 580 { | 589 { |
| 581 #ifdef ENABLE_DEBUG_RESULT | 590 #ifdef ENABLE_DEBUG_RESULT |
| 582 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); |
| 583 CPluginDebug::DebugResultHiding(tag, L"class:" + className, classIt- >second.m_filterText); | 592 CPluginDebug::DebugResultHiding(tag, L"class:" + className, classIt- >second.m_filterText); |
| 584 #endif | 593 #endif |
| 585 return true; | 594 return true; |
| 586 } | 595 } |
| 587 } | 596 } |
| 597 token = wcstok_s(nullptr, L" \t\n\r", &nextToken); | |
| 588 } | 598 } |
| 589 } | 599 } |
| 590 | 600 |
| 591 // Search tag filters | 601 // Search tag filters |
| 592 auto tagItEnum = m_elementHideTags.equal_range(tag); | 602 auto tagItEnum = m_elementHideTags.equal_range(tag); |
| 593 for (auto tagIt = tagItEnum.first; tagIt != tagItEnum.second; ++ tagIt) | 603 for (auto tagIt = tagItEnum.first; tagIt != tagItEnum.second; ++tagIt) |
|
sergei
2015/11/30 12:37:53
additional space after `++`
Eric
2015/11/30 15:54:06
Done.
| |
| 594 { | 604 { |
| 595 if (tagIt->second.IsMatchFilterElementHide(pEl)) | 605 if (tagIt->second.IsMatchFilterElementHide(pEl)) |
| 596 { | 606 { |
| 597 #ifdef ENABLE_DEBUG_RESULT | 607 #ifdef ENABLE_DEBUG_RESULT |
| 598 DEBUG_HIDE_EL(indent + L"HideEl::Found (tag) filter:" + tagIt->second.m_ filterText); | 608 DEBUG_HIDE_EL(indent + L"HideEl::Found (tag) filter:" + tagIt->second.m_ filterText); |
| 599 CPluginDebug::DebugResultHiding(tag, L"-", tagIt->second.m_filterText); | 609 CPluginDebug::DebugResultHiding(tag, L"-", tagIt->second.m_filterText); |
| 600 #endif | 610 #endif |
| 601 return true; | 611 return true; |
| 602 } | 612 } |
| 603 } | 613 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 645 | 655 |
| 646 void CPluginFilter::ClearFilters() | 656 void CPluginFilter::ClearFilters() |
| 647 { | 657 { |
| 648 // Clear filter maps | 658 // Clear filter maps |
| 649 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 659 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); |
| 650 m_elementHideTags.clear(); | 660 m_elementHideTags.clear(); |
| 651 m_elementHideTagsId.clear(); | 661 m_elementHideTagsId.clear(); |
| 652 m_elementHideTagsClass.clear(); | 662 m_elementHideTagsClass.clear(); |
| 653 } | 663 } |
| 654 | 664 |
| 655 bool CPluginFilter::ShouldBlock(const std::wstring& src, AdblockPlus::FilterEngi ne::ContentType contentType, const std::wstring& domain, bool addDebug) const | |
| 656 { | |
| 657 std::wstring srcTrimmed = TrimString(src); | |
| 658 | |
| 659 // We should not block the empty string, so all filtering does not make sense | |
| 660 // Therefore we just return | |
| 661 if (srcTrimmed.empty()) | |
| 662 { | |
| 663 return false; | |
| 664 } | |
| 665 | |
| 666 CPluginSettings* settings = CPluginSettings::GetInstance(); | |
| 667 | |
| 668 CPluginClient* client = CPluginClient::GetInstance(); | |
| 669 bool result = client->Matches(srcTrimmed, contentType, domain); | |
| 670 | |
| 671 #ifdef ENABLE_DEBUG_RESULT | |
| 672 if (addDebug) | |
| 673 { | |
| 674 std::wstring type = ToUtf16String(AdblockPlus::FilterEngine::ContentTypeToSt ring(contentType)); | |
| 675 if (result) | |
| 676 { | |
| 677 CPluginDebug::DebugResultBlocking(type, srcTrimmed, domain); | |
| 678 } | |
| 679 else | |
| 680 { | |
| 681 CPluginDebug::DebugResultIgnoring(type, srcTrimmed, domain); | |
| 682 } | |
| 683 } | |
| 684 #endif | |
| 685 return result; | |
| 686 } | |
| LEFT | RIGHT |