Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: src/plugin/PluginFilter.cpp

Issue 29331055: Issue #1234 - Remove 'CString' from PluginFilter.* (Closed)
Patch Set: address comments Created Nov. 30, 2015, 3:51 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
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-2015 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 "mlang.h" 26 #include "mlang.h"
27 #include "TokenSequence.h"
27 #include "..\shared\CriticalSection.h" 28 #include "..\shared\CriticalSection.h"
28 #include "..\shared\Utils.h" 29 #include "..\shared\Utils.h"
29 #include "..\shared\MsHTMLUtils.h" 30 #include "..\shared\MsHTMLUtils.h"
30 31
31 // The filters are described at http://adblockplus.org/en/filters 32 // The filters are described at http://adblockplus.org/en/filters
32 33
33 static CriticalSection s_criticalSectionFilterMap; 34 static CriticalSection s_criticalSectionFilterMap;
34 35
35 // ============================================================================ 36 namespace
36 // CFilterElementHideAttrSelector
37 // ============================================================================
38
39 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector() : m_type(TYPE_N ONE), m_pos(POS_NONE), m_bstrAttr(NULL)
40 { 37 {
38 std::wstring ToLowerString(const std::wstring& s)
39 {
40 return ToWstring(ToCString(s).MakeLower());
Oleksandr 2015/12/04 01:03:16 Converting to CString and back seems redundant. Ho
Eric 2015/12/06 17:39:56 I put this in the commit message as out-of-scope.
41 }
41 } 42 }
42 43
43 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector(const CFilterElem entHideAttrSelector& filter)
44 {
45 m_type = filter.m_type;
46 m_pos = filter.m_pos;
47 m_bstrAttr = filter.m_bstrAttr;
48
49 m_value = filter.m_value;
50 }
51
52 CFilterElementHideAttrSelector::~CFilterElementHideAttrSelector()
53 {
54 }
55
56
57 // ============================================================================ 44 // ============================================================================
58 // CFilterElementHide 45 // CFilterElementHide
59 // ============================================================================ 46 // ============================================================================
47 namespace
48 {
49 class ElementHideParseException
50 : public std::runtime_error
51 {
52 std::string message(const std::wstring& filterText, const std::string& reaso n)
53 {
54 std::string s(
55 "CFilterElementHide::CFilterElementHide, error parsing selector \""
56 + ToUtf8String(filterText) + "\" (" + reason + ")"
57 );
58 DEBUG_FILTER(ToUtf16String(s));
59 return s;
60 }
61 public:
62 ElementHideParseException(const std::wstring& filterText, const std::string& reason)
63 : std::runtime_error(message(filterText, reason))
64 {}
65 };
66 }
60 67
61 CFilterElementHide::CFilterElementHide(const CString& filterText) : m_filterText (filterText), m_type(ETraverserComplexType::TRAVERSER_TYPE_ERROR) 68 CFilterElementHide::CFilterElementHide(const std::wstring& filterText)
69 : m_filterText(filterText), m_type(ETraverserComplexType::TRAVERSER_TYPE_ERROR )
62 { 70 {
71 std::wstring filterSuffix(filterText); // The unparsed remainder of the input filter text
72
63 // Find tag name, class or any (*) 73 // Find tag name, class or any (*)
64 CString filterString = filterText; 74 wchar_t firstTag = filterText[0];
65
66 wchar_t firstTag = filterString.GetAt(0);
67 // Any tag
68 if (firstTag == '*') 75 if (firstTag == '*')
69 { 76 {
70 filterString = filterString.Mid(1); 77 // Any tag
78 filterSuffix = filterSuffix.substr(1);
71 } 79 }
72 // Any tag (implicitely)
73 else if (firstTag == '[' || firstTag == '.' || firstTag == '#') 80 else if (firstTag == '[' || firstTag == '.' || firstTag == '#')
74 { 81 {
82 // Any tag (implicitly)
75 } 83 }
76 // Real tag
77 else if (isalnum(firstTag)) 84 else if (isalnum(firstTag))
78 { 85 {
79 //TODO: Add support for descendant selectors 86 // Real tag
80 int pos = filterString.FindOneOf(L".#[("); 87 //TODO: Add support for descendant selectors
81 88 auto pos = filterSuffix.find_first_of(L".#[(");
82 if (pos < 0) 89 if (pos == std::wstring::npos)
83 pos = filterString.GetLength(); 90 {
84 m_tag = filterString.Left(pos).MakeLower(); 91 pos = filterSuffix.length();
85 92 }
86 filterString = filterString.Mid(pos); 93 m_tag = ToLowerString(filterSuffix.substr(0, pos));
94 filterSuffix = filterSuffix.substr(pos);
87 } 95 }
88 // Error
89 else 96 else
90 { 97 {
91 DEBUG_FILTER("Filter::Error parsing selector:" + filterText + " (invalid tag )"); 98 // Error
92 throw std::runtime_error(CStringA("Filter::Error parsing selector:" + filter Text + " (invalid tag)").GetString()); 99 throw ElementHideParseException(filterText, "invalid tag");
93 } 100 }
94 101
95 // Find Id and class name 102 // Find Id and class name
96 103 if (!filterSuffix.empty())
97 if (!filterString.IsEmpty())
98 { 104 {
99 wchar_t firstId = filterString.GetAt(0); 105 wchar_t firstId = filterSuffix[0];
100 106
101 // Id 107 // Id
102 if (firstId == '#') 108 if (firstId == '#')
103 { 109 {
104 int pos = filterString.Find('['); 110 auto pos = filterSuffix.find('[');
105 if (pos < 0) 111 if (pos == std::wstring::npos)
106 { 112 {
107 pos = filterString.GetLength(); 113 pos = filterSuffix.length();
108 } 114 }
109 m_tagId = filterString.Mid(1, pos - 1); 115 m_tagId = filterSuffix.substr(1, pos - 1);
110 filterString = filterString.Mid(pos); 116 filterSuffix = filterSuffix.substr(pos);
111 pos = m_tagId.Find(L"."); 117 pos = m_tagId.find(L".");
112 if (pos > 0) 118 if (pos != std::wstring::npos)
113 { 119 {
114 m_tagClassName = m_tagId.Mid(pos + 1); 120 if (pos == 0)
115 m_tagId = m_tagId.Left(pos); 121 {
122 throw ElementHideParseException(filterText, "empty tag id");
123 }
124 m_tagClassName = m_tagId.substr(pos + 1);
125 m_tagId = m_tagId.substr(0, pos);
116 } 126 }
117 } 127 }
118 // Class name 128 // Class name
119 else if (firstId == '.') 129 else if (firstId == '.')
120 { 130 {
121 int pos = filterString.Find('['); 131 auto pos = filterSuffix.find('[');
122 if (pos < 0) 132 if (pos == std::wstring::npos)
123 { 133 {
124 pos = filterString.GetLength(); 134 pos = filterSuffix.length();
125 } 135 }
126 m_tagClassName = filterString.Mid(1, pos - 1); 136 m_tagClassName = filterSuffix.substr(1, pos - 1);
127 filterString = filterString.Mid(pos); 137 filterSuffix = filterSuffix.substr(pos);
128 } 138 }
129 } 139 }
130 140
131 char chAttrStart = '['; 141 while (!filterSuffix.empty())
132 char chAttrEnd = ']'; 142 {
143 if (filterSuffix[0] != '[')
144 {
145 throw ElementHideParseException(filterText, "expected '['");
146 }
147 auto endPos = filterSuffix.find(']') ;
148 if (endPos == std::wstring::npos)
149 {
150 throw ElementHideParseException(filterText, "expected ']'");
151 }
152 std::wstring arg = filterSuffix.substr(1, endPos - 1);
153 filterSuffix = filterSuffix.substr(endPos + 1);
133 154
134 while (!filterString.IsEmpty()) 155 CFilterElementHideAttrSelector attrSelector;
135 { 156 auto posEquals = arg.find('=');
136 if (filterString.GetAt(0) != chAttrStart) 157 if (posEquals != std::wstring::npos)
137 { 158 {
138 DEBUG_FILTER("Filter::Error parsing selector:" + filterText + " (more data )"); 159 if (posEquals == 0)
139 throw std::runtime_error(CStringA("Filter::Error parsing selector:" + filt erText + " (more data)").GetString());
140 }
141 int endPos = filterString.Find(']') ;
142 if (endPos < 0)
143 {
144 DEBUG_FILTER("Filter::Error parsing selector:" + filterText + " (more data )");
145 throw std::runtime_error(CStringA("Filter::Error parsing selector:" + filt erText + " (more data)").GetString());
146 }
147
148 CFilterElementHideAttrSelector attrSelector;
149
150 CString arg = filterString.Mid(1, endPos - 1);
151 filterString = filterString.Mid(endPos + 1);
152
153 int delimiterPos = arg.Find('=');
154 if (delimiterPos > 0)
155 {
156 attrSelector.m_value = arg.Mid(delimiterPos + 1);
157 if (attrSelector.m_value.GetLength() >= 2 && attrSelector.m_value.GetAt(0) == '\"' && attrSelector.m_value.GetAt(attrSelector.m_value.GetLength() - 1) == '\"')
158 { 160 {
159 attrSelector.m_value = attrSelector.m_value.Mid(1, attrSelector.m_value. GetLength() - 2); 161 throw ElementHideParseException(filterText, "empty attribute name before '='");
162 }
163 attrSelector.m_value = arg.substr(posEquals + 1);
164 if (attrSelector.m_value.length() >= 2 && attrSelector.m_value[0] == '\"' && attrSelector.m_value[attrSelector.m_value.length() - 1] == '\"')
165 {
166 attrSelector.m_value = attrSelector.m_value.substr(1, attrSelector.m_val ue.length() - 2);
160 } 167 }
161 168
162 if (arg.GetAt(delimiterPos - 1) == '^') 169 if (arg[posEquals - 1] == '^')
163 { 170 {
164 attrSelector.m_bstrAttr = arg.Left(delimiterPos - 1);
165 attrSelector.m_pos = CFilterElementHideAttrPos::STARTING; 171 attrSelector.m_pos = CFilterElementHideAttrPos::STARTING;
166 } 172 }
167 else if (arg.GetAt(delimiterPos - 1) == '*') 173 else if (arg[posEquals - 1] == '*')
168 { 174 {
169 attrSelector.m_bstrAttr = arg.Left(delimiterPos - 1);
170 attrSelector.m_pos = CFilterElementHideAttrPos::ANYWHERE; 175 attrSelector.m_pos = CFilterElementHideAttrPos::ANYWHERE;
171 } 176 }
172 else if (arg.GetAt(delimiterPos - 1) == '$') 177 else if (arg[posEquals - 1] == '$')
173 { 178 {
174 attrSelector.m_bstrAttr = arg.Left(delimiterPos - 1);
175 attrSelector.m_pos = CFilterElementHideAttrPos::ENDING; 179 attrSelector.m_pos = CFilterElementHideAttrPos::ENDING;
176 } 180 }
181 if (attrSelector.m_pos != CFilterElementHideAttrPos::POS_NONE)
182 {
183 if (posEquals == 1)
184 {
185 throw ElementHideParseException(filterText, "empty attribute name befo re " + std::string(1, static_cast<char>(arg[0])) + "'='");
186 }
187 attrSelector.m_attr = arg.substr(0, posEquals - 1);
188 }
177 else 189 else
178 { 190 {
179 attrSelector.m_bstrAttr = arg.Left(delimiterPos);
180 attrSelector.m_pos = CFilterElementHideAttrPos::EXACT; 191 attrSelector.m_pos = CFilterElementHideAttrPos::EXACT;
192 attrSelector.m_attr = arg.substr(0, posEquals);
181 } 193 }
182 } 194 }
183 CString tag = attrSelector.m_bstrAttr; 195
184 if (tag == "style") 196 if (attrSelector.m_attr == L"style")
185 { 197 {
186 attrSelector.m_type = CFilterElementHideAttrType::STYLE; 198 attrSelector.m_type = CFilterElementHideAttrType::STYLE;
187 attrSelector.m_value.MakeLower(); 199 attrSelector.m_value = ToLowerString(attrSelector.m_value);
188 } 200 }
189 else if (tag == "id") 201 else if (attrSelector.m_attr == L"id")
190 { 202 {
191 attrSelector.m_type = CFilterElementHideAttrType::ID; 203 attrSelector.m_type = CFilterElementHideAttrType::ID;
192 } 204 }
193 else if (tag == "class") 205 else if (attrSelector.m_attr == L"class")
194 { 206 {
195 attrSelector.m_type = CFilterElementHideAttrType::CLASS; 207 attrSelector.m_type = CFilterElementHideAttrType::CLASS;
196 } 208 }
197 m_attributeSelectors.push_back(attrSelector); 209 m_attributeSelectors.push_back(attrSelector);
198
199 } 210 }
200 211
201 // End check 212 // End check
202 if (!filterString.IsEmpty()) 213 if (!filterSuffix.empty())
203 { 214 {
204 DEBUG_FILTER("Filter::Error parsing selector:" + filterFile + "/" + filterTe xt + " (more data)") 215 throw ElementHideParseException(filterText, "extra characters at end");
205 throw new std::runtime_error(CStringA("Filter::Error parsing selector:" + f ilterText + " (more data)").GetString());
206 } 216 }
207 } 217 }
208 218
209 CFilterElementHide::CFilterElementHide(const CFilterElementHide& filter) 219 CFilterElementHide::CFilterElementHide(const CFilterElementHide& filter)
210 { 220 {
211 m_filterText = filter.m_filterText; 221 m_filterText = filter.m_filterText;
212 222
213 m_tagId = filter.m_tagId; 223 m_tagId = filter.m_tagId;
214 m_tagClassName = filter.m_tagClassName; 224 m_tagClassName = filter.m_tagClassName;
215 225
(...skipping 27 matching lines...) Expand all
243 CFilter::CFilter() : m_isMatchCase(false), m_isFirstParty(false), 253 CFilter::CFilter() : m_isMatchCase(false), m_isFirstParty(false),
244 m_isThirdParty(false), 254 m_isThirdParty(false),
245 m_isFromStart(false), m_isFromEnd(false), m_hitCount(0) 255 m_isFromStart(false), m_isFromEnd(false), m_hitCount(0)
246 { 256 {
247 } 257 }
248 258
249 259
250 bool CFilterElementHide::IsMatchFilterElementHide(IHTMLElement* pEl) const 260 bool CFilterElementHide::IsMatchFilterElementHide(IHTMLElement* pEl) const
251 { 261 {
252 HRESULT hr; 262 HRESULT hr;
253 263 /*
254 if (!m_tagId.IsEmpty()) 264 * If a tag id is specified, it must match
265 */
266 if (!m_tagId.empty())
255 { 267 {
256 CComBSTR id; 268 CComBSTR idBstr;
257 hr = pEl->get_id(&id); 269 if (FAILED(pEl->get_id(&idBstr)) || !idBstr || m_tagId != ToWstring(idBstr))
258 if ((hr != S_OK) || (id != CComBSTR(m_tagId)))
259 { 270 {
260 return false; 271 return false;
261 } 272 }
262 } 273 }
263 if (!m_tagClassName.IsEmpty()) 274 /*
275 * If a class name is specified, it must match
276 */
277 if (!m_tagClassName.empty())
264 { 278 {
265 CComBSTR classNameBSTR; 279 CComBSTR classNameListBstr;
266 hr = pEl->get_className(&classNameBSTR); 280 hr = pEl->get_className(&classNameListBstr);
267 if (hr == S_OK) 281 if (FAILED(hr) || !classNameListBstr)
268 { 282 {
269 CString className = classNameBSTR; 283 return false; // We can't match a class name if there's no class name
270 int start = 0; 284 }
271 CString specificClass; 285 std::wstring classNameList(ToWstring(classNameListBstr));
272 bool foundMatch = false; 286 if (classNameList.empty())
273 while ((specificClass = className.Tokenize(L" ", start)) != L"") 287 {
288 return false;
289 }
290 // TODO: Consider case of multiple classes. (m_tagClassName can be something like "foo.bar")
291 /*
292 * Match when 'm_tagClassName' appears as a token within classNameList
293 */
294 bool foundMatch = false;
295 TokenSequence<std::wstring> ts(classNameList, L" ");
296 for (auto iterClassName = ts.cbegin(); iterClassName != ts.cend(); ++iterCla ssName)
297 {
298 if (*iterClassName == m_tagClassName)
274 { 299 {
275 // TODO: Consider case of multiple classes. (m_tagClassName can be somet hing like "foo.bar") 300 foundMatch = true;
276 if (specificClass == m_tagClassName) 301 break;
277 {
278 foundMatch = true;
279 }
280 }
281 if (!foundMatch)
282 {
283 return false;
284 } 302 }
285 } 303 }
286 } 304 if (!foundMatch)
287 if (!m_tag.IsEmpty())
288 {
289 CComBSTR tagName;
290 hr = pEl->get_tagName(&tagName);
291 tagName.ToLower();
292 if ((hr != S_OK) || (tagName != CComBSTR(m_tag)))
293 { 305 {
294 return false; 306 return false;
295 } 307 }
296 } 308 }
297 309 /*
298 // Check attributes 310 * If a tag name is specified, it must match
299 for (std::vector<CFilterElementHideAttrSelector>::const_iterator attrIt = m_at tributeSelectors.begin(); 311 */
300 attrIt != m_attributeSelectors.end(); ++ attrIt) 312 if (!m_tag.empty())
301 { 313 {
302 ATL::CString value; 314 CComBSTR tagNameBstr;
315 if (FAILED(pEl->get_tagName(&tagNameBstr)) || !tagNameBstr)
316 {
317 return false;
318 }
319 if (m_tag != ToLowerString(ToWstring(tagNameBstr)))
320 {
321 return false;
322 }
323 }
324 /*
325 * Match each attribute
326 */
327 for (auto attrIt = m_attributeSelectors.begin(); attrIt != m_attributeSelector s.end(); ++attrIt)
328 {
329 std::wstring value;
303 bool attrFound = false; 330 bool attrFound = false;
304 if (attrIt->m_type == CFilterElementHideAttrType::STYLE) 331 if (attrIt->m_type == CFilterElementHideAttrType::STYLE)
305 { 332 {
306 CComPtr<IHTMLStyle> pStyle; 333 CComPtr<IHTMLStyle> pStyle;
307 if (SUCCEEDED(pEl->get_style(&pStyle)) && pStyle) 334 if (SUCCEEDED(pEl->get_style(&pStyle)) && pStyle)
308 { 335 {
309 CComBSTR bstrStyle; 336 CComBSTR styleBstr;
310 337 if (SUCCEEDED(pStyle->get_cssText(&styleBstr)) && styleBstr)
311 if (SUCCEEDED(pStyle->get_cssText(&bstrStyle)) && bstrStyle)
312 { 338 {
313 value = bstrStyle; 339 value = ToLowerString(ToWstring(styleBstr));
314 value.MakeLower();
315 attrFound = true; 340 attrFound = true;
316 } 341 }
317 } 342 }
318 } 343 }
319 else if (attrIt->m_type == CFilterElementHideAttrType::CLASS) 344 else if (attrIt->m_type == CFilterElementHideAttrType::CLASS)
320 { 345 {
321 CComBSTR bstrClassNames; 346 CComBSTR classNamesBstr;
322 if (SUCCEEDED(pEl->get_className(&bstrClassNames)) && bstrClassNames) 347 if (SUCCEEDED(pEl->get_className(&classNamesBstr)) && classNamesBstr)
323 { 348 {
324 value = bstrClassNames; 349 value = ToWstring(classNamesBstr);
325 attrFound = true; 350 attrFound = true;
326 } 351 }
327 } 352 }
328 else if (attrIt->m_type == CFilterElementHideAttrType::ID) 353 else if (attrIt->m_type == CFilterElementHideAttrType::ID)
329 { 354 {
330 CComBSTR bstrId; 355 CComBSTR idBstr;
331 if (SUCCEEDED(pEl->get_id(&bstrId)) && bstrId) 356 if (SUCCEEDED(pEl->get_id(&idBstr)) && idBstr)
332 { 357 {
333 value = bstrId; 358 value = ToWstring(idBstr);
334 attrFound = true; 359 attrFound = true;
335 } 360 }
336 } 361 }
337 else 362 else
338 { 363 {
339 auto attributeValue = GetHtmlElementAttribute(*pEl, attrIt->m_bstrAttr); 364 CComBSTR attrArgument(attrIt->m_attr.length(), attrIt->m_attr.c_str());
340 if (attrFound = attributeValue.isAttributeFound) 365 auto x = GetHtmlElementAttribute(*pEl, attrArgument);
366 attrFound = x.isAttributeFound;
367 if (attrFound)
341 { 368 {
342 value = ToCString(attributeValue.attributeValue); 369 value = x.attributeValue;
343 } 370 }
344 } 371 }
345 372
346 if (attrFound) 373 if (attrFound)
347 { 374 {
348 if (attrIt->m_pos == CFilterElementHideAttrPos::EXACT) 375 if (attrIt->m_pos == CFilterElementHideAttrPos::EXACT)
349 { 376 {
350 // TODO: IE rearranges the style attribute completely. Figure out if any thing can be done about it. 377 // TODO: IE rearranges the style attribute completely. Figure out if any thing can be done about it.
351 if (value != attrIt->m_value) 378 if (value != attrIt->m_value)
352 return false; 379 return false;
353 } 380 }
354 else if (attrIt->m_pos == CFilterElementHideAttrPos::STARTING) 381 else if (attrIt->m_pos == CFilterElementHideAttrPos::STARTING)
355 { 382 {
356 if (value.Left(attrIt->m_value.GetLength()) != attrIt->m_value) 383 if (value.compare(0, attrIt->m_value.length(), attrIt->m_value) != 0)
357 return false; 384 return false;
358 } 385 }
359 else if (attrIt->m_pos == CFilterElementHideAttrPos::ENDING) 386 else if (attrIt->m_pos == CFilterElementHideAttrPos::ENDING)
360 { 387 {
361 if (value.Right(attrIt->m_value.GetLength()) != attrIt->m_value) 388 size_t valueLength = value.length();
389 size_t attrLength = attrIt->m_value.length();
390 if (valueLength < attrLength)
391 return false;
392 if (value.compare(valueLength - attrLength, attrLength, attrIt->m_value) != 0)
362 return false; 393 return false;
363 } 394 }
364 else if (attrIt->m_pos == CFilterElementHideAttrPos::ANYWHERE) 395 else if (attrIt->m_pos == CFilterElementHideAttrPos::ANYWHERE)
365 { 396 {
366 if (value.Find(attrIt->m_value) < 0) 397 if (value.find(attrIt->m_value) == std::wstring::npos)
367 return false; 398 return false;
368 } 399 }
369 else if (attrIt->m_value.IsEmpty()) 400 else if (attrIt->m_value.empty())
370 { 401 {
371 return true; 402 return true;
372 } 403 }
373 } 404 }
374 else 405 else
375 { 406 {
376 return false; 407 return false;
377 } 408 }
378 } 409 }
379 410
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 447
417 return true; 448 return true;
418 } 449 }
419 450
420 451
421 452
422 // ============================================================================ 453 // ============================================================================
423 // CPluginFilter 454 // CPluginFilter
424 // ============================================================================ 455 // ============================================================================
425 456
426 CPluginFilter::CPluginFilter(const CString& dataPath) : m_dataPath(dataPath) 457 CPluginFilter::CPluginFilter(const std::wstring& dataPath)
458 : m_dataPath(dataPath)
427 { 459 {
428 ClearFilters(); 460 ClearFilters();
429 } 461 }
430 462
431 463
432 bool CPluginFilter::AddFilterElementHide(CString filterText) 464 bool CPluginFilter::AddFilterElementHide(std::wstring filterText)
433 { 465 {
434 DEBUG_FILTER("Input: " + filterText + " filterFile" + filterFile); 466 DEBUG_FILTER(L"Input: " + filterText + L" filterFile" + filterFile);
435 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); 467 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
436 { 468 {
437 CString filterString = filterText;
438 // Create filter descriptor 469 // Create filter descriptor
439 std::auto_ptr<CFilterElementHide> filter; 470 std::auto_ptr<CFilterElementHide> filter;
440
441 CString wholeFilterString = filterString;
442 wchar_t separatorChar; 471 wchar_t separatorChar;
443 do 472 do
444 { 473 {
445 int chunkEnd = filterText.FindOneOf(L"+>"); 474 auto chunkEnd = filterText.find_first_of(L"+>");
446 if (chunkEnd > 0) 475 if (chunkEnd != std::wstring::npos && chunkEnd > 0)
447 { 476 {
448 separatorChar = filterText.GetAt(chunkEnd); 477 separatorChar = filterText[chunkEnd];
449 } 478 }
450 else 479 else
451 { 480 {
452 chunkEnd = filterText.GetLength(); 481 chunkEnd = filterText.length();
453 separatorChar = L'\0'; 482 separatorChar = L'\0';
454 } 483 }
455 484
456 CString filterChunk = filterText.Left(chunkEnd).TrimRight();
457 std::auto_ptr<CFilterElementHide> filterParent(filter); 485 std::auto_ptr<CFilterElementHide> filterParent(filter);
458 486 filter.reset(new CFilterElementHide(TrimStringRight(filterText.substr(0, c hunkEnd))));
459 filter.reset(new CFilterElementHide(filterChunk));
460
461 if (filterParent.get() != 0) 487 if (filterParent.get() != 0)
462 { 488 {
463 filter->m_predecessor.reset(filterParent.release()); 489 filter->m_predecessor.reset(filterParent.release());
464 } 490 }
465 491
466 if (separatorChar != L'\0') // complex selector 492 if (separatorChar != L'\0') // complex selector
467 { 493 {
468 filterText = filterText.Mid(chunkEnd + 1).TrimLeft(); 494 filterText = TrimStringLeft(filterText.substr(chunkEnd + 1));
469 if (separatorChar == '+') 495 if (separatorChar == '+')
470 filter->m_type = CFilterElementHide::TRAVERSER_TYPE_IMMEDIATE; 496 filter->m_type = CFilterElementHide::TRAVERSER_TYPE_IMMEDIATE;
471 else if (separatorChar == '>') 497 else if (separatorChar == '>')
472 filter->m_type = CFilterElementHide::TRAVERSER_TYPE_PARENT; 498 filter->m_type = CFilterElementHide::TRAVERSER_TYPE_PARENT;
473 } 499 }
474 else // Terminating element (simple selector) 500 else // Terminating element (simple selector)
475 { 501 {
476 if (!filter->m_tagId.IsEmpty()) 502 if (!filter->m_tagId.empty())
477 { 503 {
478 m_elementHideTagsId.insert(std::make_pair(std::make_pair(filter->m_tag , filter->m_tagId), *filter)); 504 m_elementHideTagsId.insert(std::make_pair(std::make_pair(filter->m_tag , filter->m_tagId), *filter));
479 } 505 }
480 else if (!filter->m_tagClassName.IsEmpty()) 506 else if (!filter->m_tagClassName.empty())
481 { 507 {
482 m_elementHideTagsClass.insert(std::make_pair(std::make_pair(filter->m_ tag, filter->m_tagClassName), *filter)); 508 m_elementHideTagsClass.insert(std::make_pair(std::make_pair(filter->m_ tag, filter->m_tagClassName), *filter));
483 } 509 }
484 else 510 else
485 { 511 {
486 std::pair<CString, CFilterElementHide> pair = std::make_pair(filter->m _tag, *filter); 512 m_elementHideTags.insert(std::make_pair(filter->m_tag, *filter));
487 m_elementHideTags.insert(pair);
488 } 513 }
489 } 514 }
490 } while (separatorChar != '\0'); 515 } while (separatorChar != '\0');
491 } 516 }
492 517
493 return true; 518 return true;
494 } 519 }
495 520
496 bool CPluginFilter::IsElementHidden(const std::wstring& tag, IHTMLElement* pEl, const std::wstring& domain, const std::wstring& indent) const 521 bool CPluginFilter::IsElementHidden(const std::wstring& tag, IHTMLElement* pEl, const std::wstring& domain, const std::wstring& indent) const
497 { 522 {
498 CString tagCString = ToCString(tag); 523 std::wstring id;
499 524 CComBSTR idBstr;
500 CString id; 525 if (SUCCEEDED(pEl->get_id(&idBstr)) && idBstr)
501 CComBSTR bstrId;
502 if (SUCCEEDED(pEl->get_id(&bstrId)) && bstrId)
503 { 526 {
504 id = bstrId; 527 id = ToWstring(idBstr);
505 } 528 }
506 529 std::wstring classNames;
507 CString classNames; 530 CComBSTR classNamesBstr;
508 CComBSTR bstrClassNames; 531 if (SUCCEEDED(pEl->get_className(&classNamesBstr)) && classNamesBstr)
509 if (SUCCEEDED(pEl->get_className(&bstrClassNames)) && bstrClassNames)
510 { 532 {
511 classNames = bstrClassNames; 533 classNames = ToWstring(classNamesBstr);
512 } 534 }
513 535
514 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); 536 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
515 { 537 {
516 // Search tag/id filters 538 // Search tag/id filters
517 if (!id.IsEmpty()) 539 if (!id.empty())
518 { 540 {
519 std::pair<TFilterElementHideTagsNamed::const_iterator, TFilterElementHideT agsNamed::const_iterator> idItEnum = 541 auto idItEnum = m_elementHideTagsId.equal_range(std::make_pair(tag, id));
520 m_elementHideTagsId.equal_range(std::make_pair(tagCString, id)); 542 for (auto idIt = idItEnum.first; idIt != idItEnum.second; ++idIt)
521 for (TFilterElementHideTagsNamed::const_iterator idIt = idItEnum.first; id It != idItEnum.second; idIt ++)
522 { 543 {
523 if (idIt->second.IsMatchFilterElementHide(pEl)) 544 if (idIt->second.IsMatchFilterElementHide(pEl))
524 { 545 {
525 #ifdef ENABLE_DEBUG_RESULT 546 #ifdef ENABLE_DEBUG_RESULT
526 DEBUG_HIDE_EL(indent + "HideEl::Found (tag/id) filter:" + idIt->second .m_filterText) 547 DEBUG_HIDE_EL(indent + L"HideEl::Found (tag/id) filter:" + idIt->secon d.m_filterText);
527 CPluginDebug::DebugResultHiding(tag, L"id:" + ToWstring(id), ToWstri ng(idIt->second.m_filterText)); 548 CPluginDebug::DebugResultHiding(tag, L"id:" + id, idIt->second.m_filte rText);
528 #endif 549 #endif
529 return true; 550 return true;
530 } 551 }
531 } 552 }
532 553
533 // Search general id 554 // Search general id
534 idItEnum = m_elementHideTagsId.equal_range(std::make_pair("", id)); 555 idItEnum = m_elementHideTagsId.equal_range(std::make_pair(L"", id));
535 for (TFilterElementHideTagsNamed::const_iterator idIt = idItEnum.first; id It != idItEnum.second; idIt ++) 556 for (auto idIt = idItEnum.first; idIt != idItEnum.second; ++idIt)
536 { 557 {
537 if (idIt->second.IsMatchFilterElementHide(pEl)) 558 if (idIt->second.IsMatchFilterElementHide(pEl))
538 { 559 {
539 #ifdef ENABLE_DEBUG_RESULT 560 #ifdef ENABLE_DEBUG_RESULT
540 DEBUG_HIDE_EL(indent + "HideEl::Found (?/id) filter:" + idIt->second.m _filterText) 561 DEBUG_HIDE_EL(indent + L"HideEl::Found (?/id) filter:" + idIt->second. m_filterText);
541 CPluginDebug::DebugResultHiding(tag, L"id:" + ToWstring(id), ToWstri ng(idIt->second.m_filterText)); 562 CPluginDebug::DebugResultHiding(tag, L"id:" + id, idIt->second.m_filte rText);
542 #endif 563 #endif
543 return true; 564 return true;
544 } 565 }
545 } 566 }
546 } 567 }
547 568
548 // Search tag/className filters 569 // Search tag/className filters
549 if (!classNames.IsEmpty()) 570 if (!classNames.empty())
550 { 571 {
551 int pos = 0; 572 TokenSequence<std::wstring> ts(classNames, L" \t\n\r");
552 CString className = classNames.Tokenize(L" \t\n\r", pos); 573 for (auto iterClassName = ts.cbegin(); iterClassName != ts.cend(); ++iterC lassName)
553 while (pos >= 0)
554 { 574 {
555 std::pair<TFilterElementHideTagsNamed::const_iterator, TFilterElementHid eTagsNamed::const_iterator> classItEnum = 575 std::wstring className = *iterClassName;
556 m_elementHideTagsClass.equal_range(std::make_pair(tagCString, classNam e)); 576 auto classItEnum = m_elementHideTagsClass.equal_range(std::make_pair(tag , className));
557 577 for (auto classIt = classItEnum.first; classIt != classItEnum.second; ++ classIt)
558 for (TFilterElementHideTagsNamed::const_iterator classIt = classItEnum.f irst; classIt != classItEnum.second; ++classIt)
559 { 578 {
560 if (classIt->second.IsMatchFilterElementHide(pEl)) 579 if (classIt->second.IsMatchFilterElementHide(pEl))
561 { 580 {
562 #ifdef ENABLE_DEBUG_RESULT 581 #ifdef ENABLE_DEBUG_RESULT
563 DEBUG_HIDE_EL(indent + "HideEl::Found (tag/class) filter:" + classIt ->second.m_filterText) 582 DEBUG_HIDE_EL(indent + L"HideEl::Found (tag/class) filter:" + classI t->second.m_filterText);
564 CPluginDebug::DebugResultHiding(tag, L"class:" + ToWstring(classNa me), ToWstring(classIt->second.m_filterText)); 583 CPluginDebug::DebugResultHiding(tag, L"class:" + className, classIt- >second.m_filterText);
565 #endif 584 #endif
566 return true; 585 return true;
567 } 586 }
568 } 587 }
569 588
570 // Search general class name 589 // Search general class name
571 classItEnum = m_elementHideTagsClass.equal_range(std::make_pair("", clas sName)); 590 classItEnum = m_elementHideTagsClass.equal_range(std::make_pair(L"", cla ssName));
572 for (TFilterElementHideTagsNamed::const_iterator classIt = classItEnum.f irst; classIt != classItEnum.second; ++ classIt) 591 for (auto classIt = classItEnum.first; classIt != classItEnum.second; ++ classIt)
573 { 592 {
574 if (classIt->second.IsMatchFilterElementHide(pEl)) 593 if (classIt->second.IsMatchFilterElementHide(pEl))
575 { 594 {
576 #ifdef ENABLE_DEBUG_RESULT 595 #ifdef ENABLE_DEBUG_RESULT
577 DEBUG_HIDE_EL(indent + L"HideEl::Found (?/class) filter:" + ToWStrin g(classIt->second.m_filterText)); 596 DEBUG_HIDE_EL(indent + L"HideEl::Found (?/class) filter:" + classIt- >second.m_filterText);
578 CPluginDebug::DebugResultHiding(tag, L"class:" + ToWstring(className ), ToWstring(classIt->second.m_filterText)); 597 CPluginDebug::DebugResultHiding(tag, L"class:" + className, classIt- >second.m_filterText);
579 #endif 598 #endif
580 return true; 599 return true;
581 } 600 }
582 } 601 }
583
584 // Next class name
585 className = classNames.Tokenize(L" \t\n\r", pos);
586 } 602 }
587 } 603 }
588 604
589 // Search tag filters 605 // Search tag filters
590 std::pair<TFilterElementHideTags::const_iterator, TFilterElementHideTags::co nst_iterator> tagItEnum 606 auto tagItEnum = m_elementHideTags.equal_range(tag);
591 = m_elementHideTags.equal_range(tagCString); 607 for (auto tagIt = tagItEnum.first; tagIt != tagItEnum.second; ++tagIt)
592 for (TFilterElementHideTags::const_iterator tagIt = tagItEnum.first; tagIt ! = tagItEnum.second; ++ tagIt)
593 { 608 {
594 if (tagIt->second.IsMatchFilterElementHide(pEl)) 609 if (tagIt->second.IsMatchFilterElementHide(pEl))
595 { 610 {
596 #ifdef ENABLE_DEBUG_RESULT 611 #ifdef ENABLE_DEBUG_RESULT
597 DEBUG_HIDE_EL(indent + "HideEl::Found (tag) filter:" + tagIt->second.m_f ilterText) 612 DEBUG_HIDE_EL(indent + L"HideEl::Found (tag) filter:" + tagIt->second.m_ filterText);
598 CPluginDebug::DebugResultHiding(tag, L"-", ToWstring(tagIt->second.m_f ilterText)); 613 CPluginDebug::DebugResultHiding(tag, L"-", tagIt->second.m_filterText);
599 #endif 614 #endif
600 return true; 615 return true;
601 } 616 }
602 } 617 }
603 } 618 }
604 619
605 return false; 620 return false;
606 } 621 }
607 622
608 bool CPluginFilter::LoadHideFilters(std::vector<std::wstring> filters) 623 bool CPluginFilter::LoadHideFilters(std::vector<std::wstring> filters)
609 { 624 {
610 ClearFilters(); 625 ClearFilters();
611 bool isRead = false; 626 bool isRead = false;
612 CPluginClient* client = CPluginClient::GetInstance(); 627 CPluginClient* client = CPluginClient::GetInstance();
613 628
614 // Parse hide string 629 // Parse hide string
615 int pos = 0; 630 int pos = 0;
616 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); 631 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
617 { 632 {
618 for (std::vector<std::wstring>::iterator it = filters.begin(); it < filters. end(); ++it) 633 for (auto it = filters.begin(); it < filters.end(); ++it)
619 { 634 {
620 CString filter((*it).c_str()); 635 std::wstring filter(TrimString(*it));
621 // If the line is not commented out 636 // If the line is not commented out
622 if (!filter.Trim().IsEmpty() && filter.GetAt(0) != '!' && filter.GetAt(0) != '[') 637 if (!filter.empty() && filter[0] != '!' && filter[0] != '[')
623 { 638 {
624 int filterType = 0; 639 int filterType = 0;
625 640
626 // See http://adblockplus.org/en/filters for further documentation 641 // See http://adblockplus.org/en/filters for further documentation
627 642
628 try 643 try
629 { 644 {
630 AddFilterElementHide(filter); 645 AddFilterElementHide(filter);
631 } 646 }
632 catch(...) 647 catch(...)
633 { 648 {
634 #ifdef ENABLE_DEBUG_RESULT 649 #ifdef ENABLE_DEBUG_RESULT
635 CPluginDebug::DebugResult(L"Error loading hide filter: " + ToWstring(f ilter)); 650 CPluginDebug::DebugResult(L"Error loading hide filter: " + filter);
636 #endif 651 #endif
637 } 652 }
638 } 653 }
639 } 654 }
640 } 655 }
641 656
642 return isRead; 657 return isRead;
643 } 658 }
644 659
645 void CPluginFilter::ClearFilters() 660 void CPluginFilter::ClearFilters()
(...skipping 30 matching lines...) Expand all
676 CPluginDebug::DebugResultBlocking(type, srcTrimmed, domain); 691 CPluginDebug::DebugResultBlocking(type, srcTrimmed, domain);
677 } 692 }
678 else 693 else
679 { 694 {
680 CPluginDebug::DebugResultIgnoring(type, srcTrimmed, domain); 695 CPluginDebug::DebugResultIgnoring(type, srcTrimmed, domain);
681 } 696 }
682 } 697 }
683 #endif 698 #endif
684 return result; 699 return result;
685 } 700 }
OLDNEW
« no previous file with comments | « src/plugin/PluginFilter.h ('k') | src/plugin/TokenSequence.h » ('j') | src/shared/Utils.h » ('J')

Powered by Google App Engine
This is Rietveld