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

Powered by Google App Engine
This is Rietveld