Left: | ||
Right: |
OLD | NEW |
---|---|
1 #include "PluginStdAfx.h" | 1 #include "PluginStdAfx.h" |
2 | 2 |
3 #include "PluginFilter.h" | 3 #include "PluginFilter.h" |
4 | 4 |
5 #if (defined PRODUCT_ADBLOCKPLUS) | 5 #if (defined PRODUCT_ADBLOCKPLUS) |
6 #include "PluginSettings.h" | 6 #include "PluginSettings.h" |
7 #include "PluginClient.h" | 7 #include "PluginClient.h" |
8 #include "PluginClientFactory.h" | 8 #include "PluginClientFactory.h" |
9 #endif | 9 #endif |
10 | 10 |
11 #include "PluginMutex.h" | 11 #include "PluginMutex.h" |
12 #include "PluginSettings.h" | 12 #include "PluginSettings.h" |
13 #include "PluginSystem.h" | 13 #include "PluginSystem.h" |
14 #include "PluginClass.h" | 14 #include "PluginClass.h" |
15 #include "mlang.h" | 15 #include "mlang.h" |
16 #include "PluginUtil.h" | |
17 #include "COM_Client.h" | |
16 | 18 |
17 #include "..\shared\CriticalSection.h" | 19 #include "..\shared\CriticalSection.h" |
18 | 20 |
19 | 21 |
20 // The filters are described at http://adblockplus.org/en/filters | 22 // The filters are described at http://adblockplus.org/en/filters |
21 | 23 |
22 static CriticalSection s_criticalSectionFilterMap; | 24 static CriticalSection s_criticalSectionFilterMap; |
23 | 25 |
24 // ============================================================================ | 26 // ============================================================================ |
25 // CFilterElementHideAttrSelector | 27 // CFilterElementHideAttrSelector |
26 // ============================================================================ | 28 // ============================================================================ |
27 | 29 |
28 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector() : m_type(TYPE_N ONE), m_pos(POS_NONE), m_bstrAttr(NULL) | 30 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector() |
31 : m_type(TYPE_NONE), m_pos(POS_NONE) | |
29 { | 32 { |
30 } | 33 } |
31 | 34 |
32 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector(const CFilterElem entHideAttrSelector& filter) | 35 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector(const CFilterElem entHideAttrSelector& filter) |
33 { | 36 { |
34 m_type = filter.m_type; | 37 m_type = filter.m_type; |
35 m_pos = filter.m_pos; | 38 m_pos = filter.m_pos; |
36 m_bstrAttr = filter.m_bstrAttr; | 39 m_attr_name = filter.m_attr_name; |
37 | 40 |
38 m_value = filter.m_value; | 41 m_value = filter.m_value; |
39 } | 42 } |
40 | 43 |
41 CFilterElementHideAttrSelector::~CFilterElementHideAttrSelector() | 44 CFilterElementHideAttrSelector::~CFilterElementHideAttrSelector() |
42 { | 45 { |
43 } | 46 } |
44 | 47 |
45 | 48 |
46 // ============================================================================ | 49 // ============================================================================ |
47 // CFilterElementHide | 50 // CFilterElementHide |
48 // ============================================================================ | 51 // ============================================================================ |
49 | 52 |
50 CFilterElementHide::CFilterElementHide(const CString& filterText) : m_filterText (filterText), m_type(ETraverserComplexType::TRAVERSER_TYPE_ERROR) | 53 CFilterElementHide::CFilterElementHide(const std::wstring & filterText) |
54 : m_filterText(filterText), m_type(ETraverserComplexType::TRAVERSER_TYPE_ERROR ) | |
51 { | 55 { |
52 // Find tag name, class or any (*) | 56 // Find tag name, class or any (*) |
53 CString filterString = filterText; | 57 std::wstring filter( filterText ); |
54 | 58 |
55 TCHAR firstTag = filterString.GetAt(0); | 59 wchar_t first_char = filterText[0]; |
56 // Any tag | 60 // Any tag |
57 if (firstTag == '*') | 61 if (first_char == L'*') |
58 { | 62 { |
59 filterString = filterString.Mid(1); | 63 filter.erase( 0, 1 ); |
60 } | 64 } |
61 // Any tag (implicitely) | 65 // Any tag (implicitely) |
62 else if (firstTag == '[' || firstTag == '.' || firstTag == '#') | 66 else if (first_char == L'[' || first_char == L'.' || first_char == L'#') |
63 { | 67 { |
64 } | 68 } |
65 // Real tag | 69 // Real tag |
66 else if (isalnum(firstTag)) | 70 else if (isalnum(first_char)) |
67 { | 71 { |
68 //TODO: Add support for descendant selectors | 72 //TODO: Add support for descendant selectors |
69 int pos = filterString.FindOneOf(L".#[("); | 73 size_t pos = filter.find_first_of( L".#[(" ); |
70 | 74 if ( pos == std::wstring::npos ) |
71 if (pos < 0) | 75 { |
72 pos = filterString.GetLength(); | 76 m_tag = filter; |
73 m_tag = filterString.Left(pos).MakeLower(); | 77 filter = L""; |
74 | 78 } |
75 filterString = filterString.Mid(pos); | 79 else |
80 { | |
81 m_tag = filter.substr( 0, pos ); | |
82 filter.erase( 0, pos ); | |
83 } | |
84 ABP::util::to_lower( m_tag ); | |
76 } | 85 } |
77 // Error | 86 // Error |
78 else | 87 else |
79 { | 88 { |
80 DEBUG_FILTER("Filter::Error parsing selector:" + filterText + " (invalid tag )"); | 89 DEBUG_FILTER("Filter::Error parsing selector:" + filterText + " (invalid tag )"); |
81 throw std::runtime_error(CStringA("Filter::Error parsing selector:" + filter Text + " (invalid tag)").GetString()); | 90 throw std::runtime_error( "Filter::Error parsing selector:" + ABP::debug::na rrow( filterText ) + " (invalid tag)" ); |
82 } | 91 } |
83 | 92 |
84 // Find Id and class name | 93 // Find Id and class name |
85 | 94 |
86 if (!filterString.IsEmpty()) | 95 if ( !filter.empty() ) |
87 { | 96 { |
88 TCHAR firstId = filterString.GetAt(0); | 97 first_char = filter[0]; |
89 | 98 |
90 // Id | 99 // Id |
91 if (firstId == '#') | 100 if (first_char == L'#') |
92 { | 101 { |
93 int pos = filterString.Find('['); | 102 filter.erase( 0, 1 ); |
94 if (pos < 0) | 103 size_t pos = filter.find( L'[' ); |
104 if ( pos == std::wstring::npos ) | |
95 { | 105 { |
96 pos = filterString.GetLength(); | 106 m_tagId = filter; |
107 filter = L""; | |
97 } | 108 } |
98 m_tagId = filterString.Mid(1, pos - 1); | 109 else |
99 filterString = filterString.Mid(pos); | |
100 pos = m_tagId.Find(L"."); | |
101 if (pos > 0) | |
102 { | 110 { |
103 m_tagClassName = m_tagId.Mid(pos + 1); | 111 m_tagId = filter.substr( 0, pos ); |
104 m_tagId = m_tagId.Left(pos); | 112 filter = filter.erase( 0, pos ); |
113 pos = m_tagId.find( L"." ); | |
114 if ( pos != std::wstring::npos ) | |
115 { | |
116 m_tagClassName = m_tagId.substr( pos + 1 ); | |
117 m_tagId = m_tagId.erase( pos ); | |
118 } | |
105 } | 119 } |
106 } | 120 } |
107 // Class name | 121 // Class name |
108 else if (firstId == '.') | 122 else if (first_char == L'.') |
109 { | 123 { |
110 int pos = filterString.Find('['); | 124 filter.erase( 0, 1 ); |
111 if (pos < 0) | 125 size_t pos = filter.find( L'[' ); |
126 if ( pos == std::wstring::npos ) | |
112 { | 127 { |
113 pos = filterString.GetLength(); | 128 m_tagClassName = filter; |
129 filter = L""; | |
114 } | 130 } |
115 m_tagClassName = filterString.Mid(1, pos - 1); | 131 else |
116 filterString = filterString.Mid(pos); | 132 { |
133 m_tagClassName = filter.substr( 0, pos ); | |
134 filter = filter.erase( 0, pos ); | |
135 } | |
117 } | 136 } |
118 } | 137 } |
119 | 138 |
120 char chAttrStart = '['; | 139 while ( !filter.empty() ) |
121 char chAttrEnd = ']'; | 140 { |
141 if ( filter[0] != L'[' ) | |
142 { | |
143 DEBUG_FILTER( L"Filter::Error parsing selector:" + filterText + L" (more d ata)" ); | |
144 throw std::runtime_error( "Filter::Error parsing selector:" + ABP::debug:: narrow( filterText ) + " (more data)" ); | |
145 } | |
146 size_t pos = filter.find( L']' ) ; | |
147 if ( pos == std::wstring::npos ) | |
148 { | |
149 DEBUG_FILTER( L"Filter::Error parsing selector:" + filterText + L" (more d ata)" ); | |
150 throw std::runtime_error( "Filter::Error parsing selector:" + ABP::debug:: narrow( filterText ) + " (more data)" ); | |
151 } | |
122 | 152 |
123 while (!filterString.IsEmpty()) | |
124 { | |
125 if (filterString.GetAt(0) != chAttrStart) | |
126 { | |
127 DEBUG_FILTER("Filter::Error parsing selector:" + filterText + " (more data )"); | |
128 throw std::runtime_error(CStringA("Filter::Error parsing selector:" + filt erText + " (more data)").GetString()); | |
129 } | |
130 int endPos = filterString.Find(']') ; | |
131 if (endPos < 0) | |
132 { | |
133 DEBUG_FILTER("Filter::Error parsing selector:" + filterText + " (more data )"); | |
134 throw std::runtime_error(CStringA("Filter::Error parsing selector:" + filt erText + " (more data)").GetString()); | |
135 } | |
136 | |
137 CFilterElementHideAttrSelector attrSelector; | 153 CFilterElementHideAttrSelector attrSelector; |
138 | 154 |
139 CString arg = filterString.Mid(1, endPos - 1); | 155 std::wstring arg = filter.substr( 1, pos - 1 ); |
140 filterString = filterString.Mid(endPos + 1); | 156 filter.erase( 0, pos + 1 ); |
141 | 157 |
142 int delimiterPos = arg.Find('='); | 158 size_t delimiterPos = arg.find( '=' ); |
143 if (delimiterPos > 0) | 159 if ( delimiterPos != std::wstring::npos ) |
144 { | 160 { |
145 attrSelector.m_value = arg.Mid(delimiterPos + 1); | 161 attrSelector.m_value = arg.substr( delimiterPos + 1 ); |
146 if (attrSelector.m_value.GetLength() >= 2 && attrSelector.m_value.GetAt(0) == '\"' && attrSelector.m_value.GetAt(attrSelector.m_value.GetLength() - 1) == '\"') | 162 if (attrSelector.m_value.length() >= 2 && attrSelector.m_value[0] == L'\"' && attrSelector.m_value[attrSelector.m_value.length() - 1] == L'\"') |
147 { | 163 { |
148 attrSelector.m_value = attrSelector.m_value.Mid(1, attrSelector.m_value. GetLength() - 2); | 164 attrSelector.m_value = attrSelector.m_value.substr(1, attrSelector.m_val ue.length() - 2); |
149 } | 165 } |
150 | 166 |
151 if (arg.GetAt(delimiterPos - 1) == '^') | 167 /* |
168 * Parse the type of match for an attribute selector. | |
169 * | |
170 * Support of standard exact match (no match type character) | |
171 * Support for IE-specific match types prefix (^), substring (*), and suff ix ($) | |
172 * No support for standard space-separated list (~) or hyphen (|) | |
173 */ | |
174 wchar_t match_type = arg[ delimiterPos - 1 ]; | |
175 if ( match_type == L'^' ) | |
152 { | 176 { |
153 attrSelector.m_bstrAttr = arg.Left(delimiterPos - 1); | 177 attrSelector.m_attr_name = arg.substr( 0, delimiterPos - 1 ); |
154 attrSelector.m_pos = CFilterElementHideAttrPos::STARTING; | 178 attrSelector.m_pos = CFilterElementHideAttrPos::STARTING; |
155 } | 179 } |
156 else if (arg.GetAt(delimiterPos - 1) == '*') | 180 else if ( match_type == L'*' ) |
157 { | 181 { |
158 attrSelector.m_bstrAttr = arg.Left(delimiterPos - 1); | 182 attrSelector.m_attr_name = arg.substr( 0, delimiterPos - 1 ); |
159 attrSelector.m_pos = CFilterElementHideAttrPos::ANYWHERE; | 183 attrSelector.m_pos = CFilterElementHideAttrPos::ANYWHERE; |
160 } | 184 } |
161 else if (arg.GetAt(delimiterPos - 1) == '$') | 185 else if ( match_type == L'$' ) |
162 { | 186 { |
163 attrSelector.m_bstrAttr = arg.Left(delimiterPos - 1); | 187 attrSelector.m_attr_name = arg.substr( 0, delimiterPos - 1 ); |
164 attrSelector.m_pos = CFilterElementHideAttrPos::ENDING; | 188 attrSelector.m_pos = CFilterElementHideAttrPos::ENDING; |
165 } | 189 } |
166 else | 190 else |
167 { | 191 { |
168 attrSelector.m_bstrAttr = arg.Left(delimiterPos); | 192 attrSelector.m_attr_name = arg.substr( 0, delimiterPos ); |
169 attrSelector.m_pos = CFilterElementHideAttrPos::EXACT; | 193 attrSelector.m_pos = CFilterElementHideAttrPos::EXACT; |
170 } | 194 } |
171 } | 195 } |
172 CString tag = attrSelector.m_bstrAttr; | 196 if ( attrSelector.m_attr_name == L"style" ) |
173 if (tag == "style") | |
174 { | 197 { |
175 attrSelector.m_type = CFilterElementHideAttrType::STYLE; | 198 attrSelector.m_type = CFilterElementHideAttrType::STYLE; |
176 attrSelector.m_value.MakeLower(); | 199 ABP::util::to_lower( attrSelector.m_value ); |
177 } | 200 } |
178 else if (tag == "id") | 201 else if ( attrSelector.m_attr_name == L"id" ) |
179 { | 202 { |
180 attrSelector.m_type = CFilterElementHideAttrType::ID; | 203 attrSelector.m_type = CFilterElementHideAttrType::ID; |
181 } | 204 } |
182 else if (tag == "class") | 205 else if ( attrSelector.m_attr_name == L"class" ) |
183 { | 206 { |
184 attrSelector.m_type = CFilterElementHideAttrType::CLASS; | 207 attrSelector.m_type = CFilterElementHideAttrType::CLASS; |
185 } | 208 } |
186 m_attributeSelectors.push_back(attrSelector); | 209 m_attributeSelectors.push_back(attrSelector); |
187 | 210 |
188 } | 211 } |
189 | 212 |
190 // End check | 213 // End check |
191 if (!filterString.IsEmpty()) | 214 if ( !filter.empty() ) |
192 { | 215 { |
193 DEBUG_FILTER("Filter::Error parsing selector:" + filterFile + "/" + filterTe xt + " (more data)") | 216 DEBUG_FILTER("Filter::Error parsing selector:" + filterFile + "/" + filterTe xt + " (more data)") |
194 throw new std::runtime_error(CStringA("Filter::Error parsing selector:" + f ilterText + " (more data)").GetString()); | 217 throw new std::runtime_error( "Filter::Error parsing selector:" + ABP::debu g::narrow( filterText ) + " (more data)" ); |
195 } | 218 } |
196 } | 219 } |
197 | 220 |
198 CFilterElementHide::CFilterElementHide(const CFilterElementHide& filter) | 221 CFilterElementHide::CFilterElementHide(const CFilterElementHide& filter) |
199 { | 222 { |
200 m_filterText = filter.m_filterText; | 223 m_filterText = filter.m_filterText; |
201 | 224 |
202 m_tagId = filter.m_tagId; | 225 m_tagId = filter.m_tagId; |
203 m_tagClassName = filter.m_tagClassName; | 226 m_tagClassName = filter.m_tagClassName; |
204 | 227 |
(...skipping 26 matching lines...) Expand all Loading... | |
231 | 254 |
232 | 255 |
233 CFilter::CFilter() : m_isMatchCase(false), m_isFirstParty(false), m_isThirdParty (false), m_contentType(CFilter::contentTypeAny), | 256 CFilter::CFilter() : m_isMatchCase(false), m_isFirstParty(false), m_isThirdParty (false), m_contentType(CFilter::contentTypeAny), |
234 m_isFromStart(false), m_isFromEnd(false), m_hitCount(0) | 257 m_isFromStart(false), m_isFromEnd(false), m_hitCount(0) |
235 { | 258 { |
236 } | 259 } |
237 | 260 |
238 | 261 |
239 bool CFilterElementHide::IsMatchFilterElementHide(IHTMLElement* pEl) const | 262 bool CFilterElementHide::IsMatchFilterElementHide(IHTMLElement* pEl) const |
240 { | 263 { |
241 HRESULT hr; | 264 Wrapper::HTML_Element element( pEl ); |
242 | 265 |
243 if (!m_tagId.IsEmpty()) | 266 if (!m_tagId.empty()) |
244 { | 267 { |
245 CComBSTR id; | 268 std::wstring id; |
246 hr = pEl->get_id(&id); | 269 if ( !element.id( id ) || !id.empty() ) |
247 if ((hr != S_OK) || (id != CComBSTR(m_tagId))) | |
248 { | 270 { |
249 return false; | 271 return false; |
250 } | 272 } |
251 } | 273 } |
252 if (!m_tagClassName.IsEmpty()) | 274 if (!m_tagClassName.empty()) |
253 { | 275 { |
254 CComBSTR classNameBSTR; | 276 std::wstring class_names; |
255 hr = pEl->get_className(&classNameBSTR); | 277 if ( element.class_name( class_names ) ) |
256 if (hr == S_OK) | |
257 { | 278 { |
258 CString className = classNameBSTR; | 279 size_t start = 0; |
259 int start = 0; | 280 std::wstring specific_class; |
260 CString specificClass; | |
261 bool foundMatch = false; | 281 bool foundMatch = false; |
262 while ((specificClass = className.Tokenize(L" ", start)) != L"") | 282 while ((specific_class = ABP::util::extract_token( class_names, start, L" ")) != L"") |
263 { | 283 { |
264 // TODO: Consider case of multiple classes. (m_tagClassName can be somet hing like "foo.bar") | 284 // TODO: Consider case of multiple classes. (m_tagClassName can be somet hing like "foo.bar") |
265 if (specificClass == m_tagClassName) | 285 if (specific_class == m_tagClassName) |
266 { | 286 { |
267 foundMatch = true; | 287 foundMatch = true; |
268 } | 288 } |
269 } | 289 } |
270 if (!foundMatch) | 290 if (!foundMatch) |
271 { | 291 { |
272 return false; | 292 return false; |
273 } | 293 } |
274 } | 294 } |
275 } | 295 } |
276 if (!m_tag.IsEmpty()) | 296 if (!m_tag.empty()) |
277 { | 297 { |
278 CComBSTR tagName; | 298 std::wstring tag_name; |
279 tagName.ToLower(); | 299 if ( ! element.tag_name( tag_name ) || tag_name != m_tag ) |
280 hr = pEl->get_tagName(&tagName); | |
281 if ((hr != S_OK) || (tagName != CComBSTR(m_tag))) | |
282 { | 300 { |
283 return false; | 301 return false; |
284 } | 302 } |
285 } | 303 } |
286 | 304 |
287 // Check attributes | 305 // Check attributes |
288 for (std::vector<CFilterElementHideAttrSelector>::const_iterator attrIt = m_at tributeSelectors.begin(); | 306 for (std::vector<CFilterElementHideAttrSelector>::const_iterator attrIt = m_at tributeSelectors.begin(); |
289 attrIt != m_attributeSelectors.end(); ++ attrIt) | 307 attrIt != m_attributeSelectors.end(); ++ attrIt) |
290 { | 308 { |
291 CString value; | 309 std::wstring value; |
292 bool attrFound = false; | 310 bool attrFound = false; |
293 if (attrIt->m_type == CFilterElementHideAttrType::STYLE) | 311 if (attrIt->m_type == CFilterElementHideAttrType::STYLE) |
294 { | 312 { |
295 CComPtr<IHTMLStyle> pStyle; | 313 CComPtr<IHTMLStyle> pStyle; |
296 if (SUCCEEDED(pEl->get_style(&pStyle)) && pStyle) | 314 if (SUCCEEDED(pEl->get_style(&pStyle)) && pStyle) |
297 { | 315 { |
298 CComBSTR bstrStyle; | 316 Wrapper::HTML_Style style( pStyle ); |
299 | 317 if ( style.CSS_text( value ) && !value.empty() ) |
300 if (SUCCEEDED(pStyle->get_cssText(&bstrStyle)) && bstrStyle) | |
301 { | 318 { |
302 value = bstrStyle; | 319 ABP::util::to_lower( value ); |
303 value.MakeLower(); | |
304 attrFound = true; | 320 attrFound = true; |
305 } | 321 } |
306 } | 322 } |
307 } | 323 } |
308 else if (attrIt->m_type == CFilterElementHideAttrType::CLASS) | 324 else if (attrIt->m_type == CFilterElementHideAttrType::CLASS) |
309 { | 325 { |
310 CComBSTR bstrClassNames; | 326 if ( element.class_name( value ) && !value.empty() ) |
311 if (SUCCEEDED(pEl->get_className(&bstrClassNames)) && bstrClassNames) | |
312 { | 327 { |
313 value = bstrClassNames; | |
314 attrFound = true; | 328 attrFound = true; |
315 } | 329 } |
316 } | 330 } |
317 else if (attrIt->m_type == CFilterElementHideAttrType::ID) | 331 else if (attrIt->m_type == CFilterElementHideAttrType::ID) |
318 { | 332 { |
319 CComBSTR bstrId; | 333 if ( element.id( value ) && !value.empty() ) |
320 if (SUCCEEDED(pEl->get_id(&bstrId)) && bstrId) | |
321 { | 334 { |
322 value = bstrId; | |
323 attrFound = true; | 335 attrFound = true; |
324 } | 336 } |
325 } | 337 } |
326 else | 338 else |
327 { | 339 { |
Eric
2014/08/05 17:00:38
The old way. Explicit type conversions, and you ha
|
Eric
2014/08/05 17:00:38
The new way. A single line.
|
328 CComVariant vAttr; | 340 attrFound = element.attribute( attrIt->m_attr_name, value ); |
329 if (SUCCEEDED(pEl->getAttribute(attrIt->m_bstrAttr, 0, &vAttr))) | |
330 { | |
331 attrFound = true; | |
332 if (vAttr.vt == VT_BSTR) | |
333 { | |
334 value = vAttr.bstrVal; | |
335 } | |
336 else if (vAttr.vt == VT_I4) | |
337 { | |
338 value.Format(L"%u", vAttr.iVal); | |
339 } | |
340 } | |
341 } | 341 } |
342 | 342 |
343 if (attrFound) | 343 if (attrFound) |
344 { | 344 { |
345 if (attrIt->m_pos == CFilterElementHideAttrPos::EXACT) | 345 if (attrIt->m_pos == CFilterElementHideAttrPos::EXACT) |
346 { | 346 { |
347 // TODO: IE rearranges the style attribute completely. Figure out if any thing can be done about it. | 347 // TODO: IE rearranges the style attribute completely. Figure out if any thing can be done about it. |
348 if (value != attrIt->m_value) | 348 if (value != attrIt->m_value) |
349 return false; | 349 return false; |
350 } | 350 } |
351 else if (attrIt->m_pos == CFilterElementHideAttrPos::STARTING) | 351 else if (attrIt->m_pos == CFilterElementHideAttrPos::STARTING) |
352 { | 352 { |
353 if (value.Left(attrIt->m_value.GetLength()) != attrIt->m_value) | 353 if ( !ABP::util::begins_with( value, attrIt->m_value ) ) |
354 { | |
354 return false; | 355 return false; |
356 } | |
355 } | 357 } |
356 else if (attrIt->m_pos == CFilterElementHideAttrPos::ENDING) | 358 else if (attrIt->m_pos == CFilterElementHideAttrPos::ENDING) |
357 { | 359 { |
358 if (value.Right(attrIt->m_value.GetLength()) != attrIt->m_value) | 360 size_t match_length = attrIt->m_value.length(); |
361 size_t value_length = value.length(); | |
362 // If the length of the value is less than that of the target match stri ng, there can't possibly be a match. | |
363 if ( value_length < match_length ) | |
364 { | |
359 return false; | 365 return false; |
366 } | |
367 // Assert value_length >= match_length | |
368 // Assert value_length - match_length >= 0 | |
369 if ( value.compare( value_length - match_length, match_length, attrIt->m _value ) != 0 ) | |
370 { | |
371 return false; | |
372 } | |
360 } | 373 } |
361 else if (attrIt->m_pos == CFilterElementHideAttrPos::ANYWHERE) | 374 else if (attrIt->m_pos == CFilterElementHideAttrPos::ANYWHERE) |
362 { | 375 { |
363 if (value.Find(attrIt->m_value) < 0) | 376 if ( value.find( attrIt->m_value) == std::wstring::npos ) |
377 { | |
364 return false; | 378 return false; |
379 } | |
365 } | 380 } |
366 else if (attrIt->m_value.IsEmpty()) | 381 else if (attrIt->m_value.empty()) |
367 { | 382 { |
368 return true; | 383 return true; |
369 } | 384 } |
370 } | 385 } |
371 else | 386 else |
372 { | 387 { |
373 return false; | 388 return false; |
374 } | 389 } |
375 } | 390 } |
376 | 391 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
413 | 428 |
414 return true; | 429 return true; |
415 } | 430 } |
416 | 431 |
417 | 432 |
418 | 433 |
419 // ============================================================================ | 434 // ============================================================================ |
420 // CPluginFilter | 435 // CPluginFilter |
421 // ============================================================================ | 436 // ============================================================================ |
422 | 437 |
423 CPluginFilter::CPluginFilter(const CString& dataPath) : m_dataPath(dataPath) | 438 CPluginFilter::CPluginFilter() |
424 { | 439 { |
425 m_contentMapText[CFilter::contentTypeDocument] = "DOCUMENT"; | 440 m_contentMapText[CFilter::contentTypeDocument] = L"DOCUMENT"; |
426 m_contentMapText[CFilter::contentTypeObject] = "OBJECT"; | 441 m_contentMapText[CFilter::contentTypeObject] = L"OBJECT"; |
427 m_contentMapText[CFilter::contentTypeImage] = "IMAGE"; | 442 m_contentMapText[CFilter::contentTypeImage] = L"IMAGE"; |
428 m_contentMapText[CFilter::contentTypeScript] = "SCRIPT"; | 443 m_contentMapText[CFilter::contentTypeScript] = L"SCRIPT"; |
429 m_contentMapText[CFilter::contentTypeOther] = "OTHER"; | 444 m_contentMapText[CFilter::contentTypeOther] = L"OTHER"; |
430 m_contentMapText[CFilter::contentTypeUnknown] = "OTHER"; | 445 m_contentMapText[CFilter::contentTypeUnknown] = L"OTHER"; |
431 m_contentMapText[CFilter::contentTypeSubdocument] = "SUBDOCUMENT"; | 446 m_contentMapText[CFilter::contentTypeSubdocument] = L"SUBDOCUMENT"; |
432 m_contentMapText[CFilter::contentTypeStyleSheet] = "STYLESHEET"; | 447 m_contentMapText[CFilter::contentTypeStyleSheet] = L"STYLESHEET"; |
433 m_contentMapText[CFilter::contentTypeXmlHttpRequest] = "XMLHTTPREQUEST"; | 448 m_contentMapText[CFilter::contentTypeXmlHttpRequest] = L"XMLHTTPREQUEST"; |
434 | 449 |
435 ClearFilters(); | 450 ClearFilters(); |
436 } | 451 } |
437 | 452 |
438 | 453 |
439 bool CPluginFilter::AddFilterElementHide(CString filterText) | 454 bool CPluginFilter::AddFilterElementHide( std::wstring filterText ) |
440 { | 455 { |
456 std::wstring filter_text = filterText; | |
441 | 457 |
442 | 458 DEBUG_FILTER( L"Input: " + filterText + L" filterFile" + filterFile ); |
443 DEBUG_FILTER("Input: " + filterText + " filterFile" + filterFile); | |
444 | 459 |
445 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 460 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); |
446 { | 461 { |
447 | |
448 CString filterString = filterText; | |
449 // Create filter descriptor | 462 // Create filter descriptor |
450 std::auto_ptr<CFilterElementHide> filter; | 463 std::auto_ptr<CFilterElementHide> filter; |
451 | 464 |
452 CString wholeFilterString = filterString; | 465 wchar_t separatorChar; |
453 TCHAR separatorChar; | |
454 do | 466 do |
455 { | 467 { |
456 int chunkEnd = filterText.FindOneOf(L"+>"); | 468 size_t separator_pos = filter_text.find_first_of( L"+>" ); |
457 if (chunkEnd > 0) | 469 if ( separator_pos != std::wstring::npos ) |
458 { | 470 { |
459 separatorChar = filterText.GetAt(chunkEnd); | 471 separatorChar = filter_text[ separator_pos ]; |
460 } | 472 } |
461 else | 473 else |
462 { | 474 { |
463 chunkEnd = filterText.GetLength(); | 475 separator_pos = filter_text.length(); |
464 separatorChar = L'\0'; | 476 separatorChar = L'\0'; |
465 } | 477 } |
466 | 478 |
467 CString filterChunk = filterText.Left(chunkEnd).TrimRight(); | 479 std::wstring filter_chunk = filter_text.substr( 0, separator_pos ); |
480 ABP::util::trim_trailing( filter_chunk ); | |
481 | |
468 std::auto_ptr<CFilterElementHide> filterParent(filter); | 482 std::auto_ptr<CFilterElementHide> filterParent(filter); |
469 | 483 filter.reset( new CFilterElementHide( filter_chunk ) ); |
470 filter.reset(new CFilterElementHide(filterChunk)); | |
471 | 484 |
472 if (filterParent.get() != 0) | 485 if (filterParent.get() != 0) |
473 { | 486 { |
474 filter->m_predecessor.reset(filterParent.release()); | 487 filter->m_predecessor.reset(filterParent.release()); |
475 } | 488 } |
476 | 489 |
477 if (separatorChar != L'\0') // complex selector | 490 if (separatorChar != L'\0') // complex selector |
478 { | 491 { |
479 filterText = filterText.Mid(chunkEnd + 1).TrimLeft(); | 492 filter_text.erase( 0, separator_pos + 1 ); |
493 ABP::util::trim_leading( filter_text ); | |
494 | |
480 if (separatorChar == '+') | 495 if (separatorChar == '+') |
481 filter->m_type = CFilterElementHide::TRAVERSER_TYPE_IMMEDIATE; | 496 filter->m_type = CFilterElementHide::TRAVERSER_TYPE_IMMEDIATE; |
482 else if (separatorChar == '>') | 497 else if (separatorChar == '>') |
483 filter->m_type = CFilterElementHide::TRAVERSER_TYPE_PARENT; | 498 filter->m_type = CFilterElementHide::TRAVERSER_TYPE_PARENT; |
484 } | 499 } |
485 else // Terminating element (simple selector) | 500 else // Terminating element (simple selector) |
486 { | 501 { |
487 if (!filter->m_tagId.IsEmpty()) | 502 if (!filter->m_tagId.empty()) |
488 { | 503 { |
489 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)); |
490 } | 505 } |
491 else if (!filter->m_tagClassName.IsEmpty()) | 506 else if (!filter->m_tagClassName.empty()) |
492 { | 507 { |
493 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)); |
494 } | 509 } |
495 else | 510 else |
496 { | 511 { |
497 std::pair<CString, CFilterElementHide> pair = std::make_pair(filter->m _tag, *filter); | 512 std::pair< std::wstring, CFilterElementHide> pair = std::make_pair(fil ter->m_tag, *filter); |
498 m_elementHideTags.insert(pair); | 513 m_elementHideTags.insert(pair); |
499 } | 514 } |
500 } | 515 } |
501 } while (separatorChar != '\0'); | 516 } while (separatorChar != '\0'); |
502 } | 517 } |
503 | 518 |
504 return true; | 519 return true; |
505 } | 520 } |
506 | 521 |
507 bool CPluginFilter::IsElementHidden(const CString& tag, IHTMLElement* pEl, const CString& domain, const CString& indent) const | 522 bool CPluginFilter::IsElementHidden(const std::wstring & tag, IHTMLElement* pEl, const std::wstring & domain, const std::wstring & indent) const |
508 { | 523 { |
509 CString id; | 524 Wrapper::HTML_Element element( pEl ); |
510 CComBSTR bstrId; | 525 std::wstring id; |
511 if (SUCCEEDED(pEl->get_id(&bstrId)) && bstrId) | 526 element.id( id ); |
512 { | |
513 id = bstrId; | |
514 } | |
515 | 527 |
516 CString classNames; | 528 std::wstring class_names; |
517 CComBSTR bstrClassNames; | 529 element.class_name( class_names ); |
518 if (SUCCEEDED(pEl->get_className(&bstrClassNames)) && bstrClassNames) | |
519 { | |
520 classNames = bstrClassNames; | |
521 } | |
522 | 530 |
523 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 531 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); |
524 { | 532 { |
525 CString domainTest = domain; | |
526 | |
527 // Search tag/id filters | 533 // Search tag/id filters |
528 if (!id.IsEmpty()) | 534 if (!id.empty()) |
529 { | 535 { |
530 std::pair<TFilterElementHideTagsNamed::const_iterator, TFilterElementHideT agsNamed::const_iterator> idItEnum = | 536 std::pair<TFilterElementHideTagsNamed::const_iterator, TFilterElementHideT agsNamed::const_iterator> idItEnum = |
531 m_elementHideTagsId.equal_range(std::make_pair(tag, id)); | 537 m_elementHideTagsId.equal_range(std::make_pair(tag, id)); |
532 for (TFilterElementHideTagsNamed::const_iterator idIt = idItEnum.first; id It != idItEnum.second; idIt ++) | 538 for (TFilterElementHideTagsNamed::const_iterator idIt = idItEnum.first; id It != idItEnum.second; idIt ++) |
533 { | 539 { |
534 if (idIt->second.IsMatchFilterElementHide(pEl)) | 540 if (idIt->second.IsMatchFilterElementHide(pEl)) |
535 { | 541 { |
536 #ifdef ENABLE_DEBUG_RESULT | 542 #ifdef ENABLE_DEBUG_RESULT |
537 DEBUG_HIDE_EL(indent + "HideEl::Found (tag/id) filter:" + idIt->second .m_filterText) | 543 DEBUG_HIDE_EL(indent + "HideEl::Found (tag/id) filter:" + idIt->second .m_filterText) |
538 CPluginDebug::DebugResultHiding(tag, "id:" + id, idIt->second.m_filt erText); | 544 CPluginDebug::DebugResultHiding(tag, std::wstring( L"id:" ) + id, id It->second.m_filterText); |
539 #endif | 545 #endif |
540 return true; | 546 return true; |
541 } | 547 } |
542 } | 548 } |
543 | 549 |
544 // Search general id | 550 // Search general id |
545 idItEnum = m_elementHideTagsId.equal_range(std::make_pair("", id)); | 551 idItEnum = m_elementHideTagsId.equal_range(std::make_pair(L"", id)); |
546 for (TFilterElementHideTagsNamed::const_iterator idIt = idItEnum.first; id It != idItEnum.second; idIt ++) | 552 for (TFilterElementHideTagsNamed::const_iterator idIt = idItEnum.first; id It != idItEnum.second; idIt ++) |
547 { | 553 { |
548 if (idIt->second.IsMatchFilterElementHide(pEl)) | 554 if (idIt->second.IsMatchFilterElementHide(pEl)) |
549 { | 555 { |
550 #ifdef ENABLE_DEBUG_RESULT | 556 #ifdef ENABLE_DEBUG_RESULT |
551 DEBUG_HIDE_EL(indent + "HideEl::Found (?/id) filter:" + idIt->second.m _filterText) | 557 DEBUG_HIDE_EL(indent + "HideEl::Found (?/id) filter:" + idIt->second.m _filterText) |
552 CPluginDebug::DebugResultHiding(tag, "id:" + id, idIt->second.m_filt erText); | 558 CPluginDebug::DebugResultHiding(tag, std::wstring( L"id:" ) + id, id It->second.m_filterText); |
553 #endif | 559 #endif |
554 return true; | 560 return true; |
555 } | 561 } |
556 } | 562 } |
557 } | 563 } |
558 | 564 |
559 // Search tag/className filters | 565 // Search tag/className filters |
560 if (!classNames.IsEmpty()) | 566 if ( !class_names.empty() ) |
561 { | 567 { |
562 int pos = 0; | 568 size_t class_names_pos = 0; |
563 CString className = classNames.Tokenize(L" \t\n\r", pos); | 569 std::wstring class_name = ABP::util::extract_token( class_names, class_nam es_pos, L" \t\n\r" ); |
564 while (pos >= 0) | 570 while ( !class_name.empty() ) |
565 { | 571 { |
566 std::pair<TFilterElementHideTagsNamed::const_iterator, TFilterElementHid eTagsNamed::const_iterator> classItEnum = | 572 std::pair<TFilterElementHideTagsNamed::const_iterator, TFilterElementHid eTagsNamed::const_iterator> classItEnum = |
567 m_elementHideTagsClass.equal_range(std::make_pair(tag, className)); | 573 m_elementHideTagsClass.equal_range( std::make_pair( tag, class_name ) ); |
568 | 574 |
569 for (TFilterElementHideTagsNamed::const_iterator classIt = classItEnum.f irst; classIt != classItEnum.second; ++classIt) | 575 for (TFilterElementHideTagsNamed::const_iterator classIt = classItEnum.f irst; classIt != classItEnum.second; ++classIt) |
570 { | 576 { |
571 if (classIt->second.IsMatchFilterElementHide(pEl)) | 577 if (classIt->second.IsMatchFilterElementHide(pEl)) |
572 { | 578 { |
573 #ifdef ENABLE_DEBUG_RESULT | 579 #ifdef ENABLE_DEBUG_RESULT |
574 DEBUG_HIDE_EL(indent + "HideEl::Found (tag/class) filter:" + classIt ->second.m_filterText) | 580 DEBUG_HIDE_EL(indent + "HideEl::Found (tag/class) filter:" + classIt ->second.m_filterText) |
575 CPluginDebug::DebugResultHiding(tag, "class:" + className, classIt ->second.m_filterText); | 581 CPluginDebug::DebugResultHiding(tag, std::wstring( L"class:" ) + c lass_name, classIt->second.m_filterText); |
576 #endif | 582 #endif |
577 return true; | 583 return true; |
578 } | 584 } |
579 } | 585 } |
580 | 586 |
581 // Search general class name | 587 // Search general class name |
582 classItEnum = m_elementHideTagsClass.equal_range(std::make_pair("", clas sName)); | 588 classItEnum = m_elementHideTagsClass.equal_range(std::make_pair(L"", cla ss_name)); |
583 for (TFilterElementHideTagsNamed::const_iterator classIt = classItEnum.f irst; classIt != classItEnum.second; ++ classIt) | 589 for (TFilterElementHideTagsNamed::const_iterator classIt = classItEnum.f irst; classIt != classItEnum.second; ++ classIt) |
584 { | 590 { |
585 if (classIt->second.IsMatchFilterElementHide(pEl)) | 591 if (classIt->second.IsMatchFilterElementHide(pEl)) |
586 { | 592 { |
587 #ifdef ENABLE_DEBUG_RESULT | 593 #ifdef ENABLE_DEBUG_RESULT |
588 DEBUG_HIDE_EL(indent + "HideEl::Found (?/class) filter:" + classIt-> second.m_filterText) | 594 DEBUG_HIDE_EL(indent + "HideEl::Found (?/class) filter:" + classIt-> second.m_filterText) |
589 CPluginDebug::DebugResultHiding(tag, "class:" + className, classIt ->second.m_filterText); | 595 CPluginDebug::DebugResultHiding(tag, std::wstring( L"class:" ) + c lass_name, classIt->second.m_filterText); |
590 #endif | 596 #endif |
591 return true; | 597 return true; |
592 } | 598 } |
593 } | 599 } |
594 | 600 |
595 // Next class name | 601 // Next class name |
596 className = classNames.Tokenize(L" \t\n\r", pos); | 602 class_name = ABP::util::extract_token( class_names, class_names_pos, L" \t\n\r" ); |
597 } | 603 } |
598 } | 604 } |
599 | 605 |
600 // Search tag filters | 606 // Search tag filters |
601 std::pair<TFilterElementHideTags::const_iterator, TFilterElementHideTags::co nst_iterator> tagItEnum | 607 std::pair<TFilterElementHideTags::const_iterator, TFilterElementHideTags::co nst_iterator> tagItEnum |
602 = m_elementHideTags.equal_range(tag); | 608 = m_elementHideTags.equal_range(tag); |
603 for (TFilterElementHideTags::const_iterator tagIt = tagItEnum.first; tagIt ! = tagItEnum.second; ++ tagIt) | 609 for (TFilterElementHideTags::const_iterator tagIt = tagItEnum.first; tagIt ! = tagItEnum.second; ++ tagIt) |
604 { | 610 { |
605 if (tagIt->second.IsMatchFilterElementHide(pEl)) | 611 if (tagIt->second.IsMatchFilterElementHide(pEl)) |
606 { | 612 { |
607 #ifdef ENABLE_DEBUG_RESULT | 613 #ifdef ENABLE_DEBUG_RESULT |
608 DEBUG_HIDE_EL(indent + "HideEl::Found (tag) filter:" + tagIt->second.m_f ilterText) | 614 DEBUG_HIDE_EL(indent + "HideEl::Found (tag) filter:" + tagIt->second.m_f ilterText) |
609 CPluginDebug::DebugResultHiding(tag, "-", tagIt->second.m_filterText); | 615 CPluginDebug::DebugResultHiding(tag, L"-", tagIt->second.m_filterText) ; |
610 #endif | 616 #endif |
611 return true; | 617 return true; |
612 } | 618 } |
613 } | 619 } |
614 } | 620 } |
615 | 621 |
616 return false; | 622 return false; |
617 } | 623 } |
618 | 624 |
619 bool CPluginFilter::LoadHideFilters(std::vector<std::wstring> filters) | 625 bool CPluginFilter::LoadHideFilters(std::vector<std::wstring> filters) |
620 { | 626 { |
621 | 627 |
622 ClearFilters(); | 628 ClearFilters(); |
623 | 629 |
624 bool isRead = false; | 630 bool isRead = false; |
625 | 631 |
626 #ifdef PRODUCT_ADBLOCKPLUS | 632 #ifdef PRODUCT_ADBLOCKPLUS |
627 CPluginClient* client = CPluginClient::GetInstance(); | 633 CPluginClient* client = CPluginClient::GetInstance(); |
628 #endif | 634 #endif |
629 | 635 |
630 // Parse hide string | 636 // Parse hide string |
631 int pos = 0; | 637 int pos = 0; |
632 | 638 |
633 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 639 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); |
634 { | 640 { |
635 for (std::vector<std::wstring>::iterator it = filters.begin(); it < filters. end(); ++it) | 641 for (std::vector<std::wstring>::iterator it = filters.begin(); it < filters. end(); ++it) |
636 { | 642 { |
637 CString filter((*it).c_str()); | 643 std::wstring filter( *it ); |
644 ABP::util::trim( filter ); | |
638 // If the line is not commented out | 645 // If the line is not commented out |
639 if (!filter.Trim().IsEmpty() && filter.GetAt(0) != '!' && filter.GetAt(0) != '[') | 646 if ( !filter.empty() && filter[0] != '!' && filter[0] != '[') |
640 { | 647 { |
641 int filterType = 0; | 648 int filterType = 0; |
642 | 649 |
643 // See http://adblockplus.org/en/filters for further documentation | 650 // See http://adblockplus.org/en/filters for further documentation |
644 | 651 |
645 try | 652 try |
646 { | 653 { |
647 AddFilterElementHide(filter); | 654 AddFilterElementHide( filter ); |
648 } | 655 } |
649 catch(...) | 656 catch(...) |
650 { | 657 { |
651 #ifdef ENABLE_DEBUG_RESULT | 658 #ifdef ENABLE_DEBUG_RESULT |
652 CPluginDebug::DebugResult(L"Error loading hide filter: " + filter); | 659 CPluginDebug::DebugResult(L"Error loading hide filter: " + filter); |
653 #endif | 660 #endif |
654 } | 661 } |
655 } | 662 } |
656 } | 663 } |
657 } | 664 } |
(...skipping 14 matching lines...) Expand all Loading... | |
672 } | 679 } |
673 m_filterMapDefault[i].clear(); | 680 m_filterMapDefault[i].clear(); |
674 } | 681 } |
675 | 682 |
676 m_elementHideTags.clear(); | 683 m_elementHideTags.clear(); |
677 m_elementHideTagsId.clear(); | 684 m_elementHideTagsId.clear(); |
678 m_elementHideTagsClass.clear(); | 685 m_elementHideTagsClass.clear(); |
679 } | 686 } |
680 } | 687 } |
681 | 688 |
682 bool CPluginFilter::ShouldBlock(CString src, int contentType, const CString& dom ain, bool addDebug) const | 689 bool CPluginFilter::ShouldBlock( std::wstring src, int contentType, const std::w string & domain, bool addDebug) const |
683 { | 690 { |
684 // We should not block the empty string, so all filtering does not make sense | 691 // We should not block the empty string, so all filtering does not make sense |
685 // Therefore we just return | 692 // Therefore we just return |
686 if (src.Trim().IsEmpty()) | 693 ABP::util::trim( src ); |
694 if (src.empty()) | |
687 { | 695 { |
688 return false; | 696 return false; |
689 } | 697 } |
690 | 698 |
691 CPluginSettings* settings = CPluginSettings::GetInstance(); | 699 CPluginSettings* settings = CPluginSettings::GetInstance(); |
692 | 700 |
693 CString type; | 701 std::wstring type; |
694 if (addDebug) | 702 if (addDebug) |
695 { | 703 { |
696 type = "OTHER"; | 704 type = L"OTHER"; |
697 | 705 |
698 std::map<int,CString>::const_iterator it = m_contentMapText.find(contentType ); | 706 std::map< int, std::wstring >::const_iterator it = m_contentMapText.find(con tentType); |
699 if (it != m_contentMapText.end()) | 707 if (it != m_contentMapText.end()) |
700 { | 708 { |
701 type = it->second; | 709 type = it->second; |
702 } | 710 } |
703 } | 711 } |
704 | 712 |
705 CPluginClient* client = CPluginClient::GetInstance(); | 713 CPluginClient* client = CPluginClient::GetInstance(); |
706 if (client->Matches(std::wstring(src), std::wstring(type), std::wstring(domain ))) | 714 if (client->Matches(std::wstring(src), type, std::wstring(domain))) |
707 { | 715 { |
708 if (addDebug) | 716 if (addDebug) |
709 { | 717 { |
710 DEBUG_FILTER("Filter::ShouldBlock " + type + " YES") | 718 DEBUG_FILTER( L"Filter::ShouldBlock " + type + L" YES" ) |
711 | 719 |
712 #ifdef ENABLE_DEBUG_RESULT | 720 #ifdef ENABLE_DEBUG_RESULT |
713 CPluginDebug::DebugResultBlocking(type, src, domain); | 721 CPluginDebug::DebugResultBlocking( type, src, domain); |
714 #endif | 722 #endif |
715 } | 723 } |
716 return true; | 724 return true; |
717 } | 725 } |
718 return false; | 726 return false; |
719 } | 727 } |
OLD | NEW |