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

Powered by Google App Engine
This is Rietveld