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

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

Issue 6433575100481536: Issue 1148 - ABP on chrome blocks ads but IE doesnt (Closed)
Patch Set: Created Nov. 10, 2014, 12:26 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 | « no previous file | src/plugin/PluginUtil.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 #include "PluginStdAfx.h" 1 #include "PluginStdAfx.h"
2 2
3 #include "PluginFilter.h" 3 #include "PluginFilter.h"
4 #include "PluginSettings.h" 4 #include "PluginSettings.h"
5 #include "PluginClient.h" 5 #include "PluginClient.h"
6 #include "PluginClientFactory.h" 6 #include "PluginClientFactory.h"
7 #include "PluginMutex.h" 7 #include "PluginMutex.h"
8 #include "PluginSettings.h" 8 #include "PluginSettings.h"
9 #include "PluginSystem.h" 9 #include "PluginSystem.h"
10 #include "PluginClass.h" 10 #include "PluginClass.h"
11 #include "mlang.h" 11 #include "mlang.h"
12 12
13 #include "..\shared\CriticalSection.h" 13 #include "..\shared\CriticalSection.h"
14 #include "..\shared\Utils.h"
14 15
15 16
16 // The filters are described at http://adblockplus.org/en/filters 17 // The filters are described at http://adblockplus.org/en/filters
17 18
18 static CriticalSection s_criticalSectionFilterMap; 19 static CriticalSection s_criticalSectionFilterMap;
19 20
21 namespace
22 {
23 // Returns attribute value and the bool flag which indicates whether the attri bute is found.
24 // For the cases like <some-tag on-some-event="do();"/> IE returns the value o f 'on-some-event'
25 // attribute as 'function(event){\ndo();\n}'. Our filters are not designed for such
26 // transformations, so this method retrives the value of (body) of /^.*?\{(bod y)\}$/ as well.
27 std::pair<std::wstring, bool> GetHtmlElementAttribute(IHTMLElement& htmlElemen t, const ATL::CComBSTR& attributeName)
28 {
29 std::pair<std::wstring, bool> retResult;
30 retResult.second = false;
31 ATL::CComVariant vAttr;
32 // Performs a property search that is not case-sensitive,
33 // and returns an interpolated value if the property is found.
34 LONG flags = 0;
35 if (FAILED(htmlElement.getAttribute(attributeName, flags, &vAttr)))
36 {
37 return retResult;
38 }
39 // we set that attribute found but it's not necessary that we can retrieve i ts value
40 retResult.second = true;
41 if (vAttr.vt == VT_BSTR && vAttr.bstrVal)
42 {
43 retResult.first.assign(vAttr.bstrVal);
44 }
45 else if (vAttr.vt == VT_I4)
46 {
47 retResult.first = std::to_wstring(vAttr.iVal);
48 }
49 else if (vAttr.vt == VT_DISPATCH)
50 {
51 wchar_t* toStringMethod = L"toString";
52 DISPID methodId = 0;
53 if (FAILED(vAttr.pdispVal->GetIDsOfNames(/*must be null iid*/IID_NULL, &to StringMethod,
54 /*cNames*/1, LOCALE_SYSTEM_DEFAULT, &methodId)))
55 {
56 return retResult;
57 }
58 ATL::CComVariant variantFunctionAsString; // result of IDispatch::Invoke
59 DISPID dispidNamed = DISPATCH_METHOD | DISPATCH_PROPERTYGET;
60 DISPPARAMS dispparams;
61 dispparams.rgvarg = &variantFunctionAsString;
62 dispparams.cArgs = 1;
63 dispparams.cNamedArgs = 1;
64 dispparams.rgdispidNamedArgs = &dispidNamed;
65 UINT ArgErr = 0;
66 if (FAILED(vAttr.pdispVal->Invoke(methodId, /*must be null iid*/IID_NULL,
67 LOCALE_SYSTEM_DEFAULT, dispidNamed, &dispparams, &variantFunctionAsStrin g, /*exception info*/nullptr,
68 &ArgErr)))
69 {
70 return retResult;
71 }
72 if (variantFunctionAsString.vt != VT_BSTR)
73 {
74 return retResult;
75 }
76 std::wstring functionAsString = variantFunctionAsString.bstrVal;
77 auto bodyBeginsAt = functionAsString.find(L'{');
78 if (bodyBeginsAt == std::wstring::npos)
79 {
80 return retResult;
81 }
82 // eat spaces
83 while (::iswspace(functionAsString[++bodyBeginsAt]));
84 auto bodyEndsAt = functionAsString.rfind(L'}');
85 if (bodyEndsAt == std::wstring::npos || bodyEndsAt < bodyBeginsAt)
86 {
87 return retResult;
88 }
89 // eat spaces
90 while(::iswspace(functionAsString[--bodyEndsAt]));
91 retResult.first = functionAsString.substr(bodyBeginsAt, bodyEndsAt - bodyB eginsAt + 1);
92 }
93 return retResult;
94 }
95 }
96
20 // ============================================================================ 97 // ============================================================================
21 // CFilterElementHideAttrSelector 98 // CFilterElementHideAttrSelector
22 // ============================================================================ 99 // ============================================================================
23 100
24 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector() : m_type(TYPE_N ONE), m_pos(POS_NONE), m_bstrAttr(NULL) 101 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector() : m_type(TYPE_N ONE), m_pos(POS_NONE), m_bstrAttr(NULL)
25 { 102 {
26 } 103 }
27 104
28 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector(const CFilterElem entHideAttrSelector& filter) 105 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector(const CFilterElem entHideAttrSelector& filter)
29 { 106 {
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 } 342 }
266 if (!foundMatch) 343 if (!foundMatch)
267 { 344 {
268 return false; 345 return false;
269 } 346 }
270 } 347 }
271 } 348 }
272 if (!m_tag.IsEmpty()) 349 if (!m_tag.IsEmpty())
273 { 350 {
274 CComBSTR tagName; 351 CComBSTR tagName;
352 hr = pEl->get_tagName(&tagName);
275 tagName.ToLower(); 353 tagName.ToLower();
276 hr = pEl->get_tagName(&tagName);
277 if ((hr != S_OK) || (tagName != CComBSTR(m_tag))) 354 if ((hr != S_OK) || (tagName != CComBSTR(m_tag)))
278 { 355 {
279 return false; 356 return false;
280 } 357 }
281 } 358 }
282 359
283 // Check attributes 360 // Check attributes
284 for (std::vector<CFilterElementHideAttrSelector>::const_iterator attrIt = m_at tributeSelectors.begin(); 361 for (std::vector<CFilterElementHideAttrSelector>::const_iterator attrIt = m_at tributeSelectors.begin();
285 attrIt != m_attributeSelectors.end(); ++ attrIt) 362 attrIt != m_attributeSelectors.end(); ++ attrIt)
286 { 363 {
287 CString value; 364 ATL::CString value;
288 bool attrFound = false; 365 bool attrFound = false;
289 if (attrIt->m_type == CFilterElementHideAttrType::STYLE) 366 if (attrIt->m_type == CFilterElementHideAttrType::STYLE)
290 { 367 {
291 CComPtr<IHTMLStyle> pStyle; 368 CComPtr<IHTMLStyle> pStyle;
292 if (SUCCEEDED(pEl->get_style(&pStyle)) && pStyle) 369 if (SUCCEEDED(pEl->get_style(&pStyle)) && pStyle)
293 { 370 {
294 CComBSTR bstrStyle; 371 CComBSTR bstrStyle;
295 372
296 if (SUCCEEDED(pStyle->get_cssText(&bstrStyle)) && bstrStyle) 373 if (SUCCEEDED(pStyle->get_cssText(&bstrStyle)) && bstrStyle)
297 { 374 {
(...skipping 14 matching lines...) Expand all
312 } 389 }
313 else if (attrIt->m_type == CFilterElementHideAttrType::ID) 390 else if (attrIt->m_type == CFilterElementHideAttrType::ID)
314 { 391 {
315 CComBSTR bstrId; 392 CComBSTR bstrId;
316 if (SUCCEEDED(pEl->get_id(&bstrId)) && bstrId) 393 if (SUCCEEDED(pEl->get_id(&bstrId)) && bstrId)
317 { 394 {
318 value = bstrId; 395 value = bstrId;
319 attrFound = true; 396 attrFound = true;
320 } 397 }
321 } 398 }
322 else 399 else
323 { 400 {
324 CComVariant vAttr; 401 auto attribute = GetHtmlElementAttribute(*pEl, attrIt->m_bstrAttr);
325 if (SUCCEEDED(pEl->getAttribute(attrIt->m_bstrAttr, 0, &vAttr))) 402 if (attrFound = attribute.second)
326 { 403 {
327 attrFound = true; 404 value = ToCString(attribute.first);
328 if (vAttr.vt == VT_BSTR)
329 {
330 value = vAttr.bstrVal;
331 }
332 else if (vAttr.vt == VT_I4)
333 {
334 value.Format(L"%u", vAttr.iVal);
335 }
336 } 405 }
337 } 406 }
338 407
339 if (attrFound) 408 if (attrFound)
340 { 409 {
341 if (attrIt->m_pos == CFilterElementHideAttrPos::EXACT) 410 if (attrIt->m_pos == CFilterElementHideAttrPos::EXACT)
342 { 411 {
343 // TODO: IE rearranges the style attribute completely. Figure out if any thing can be done about it. 412 // TODO: IE rearranges the style attribute completely. Figure out if any thing can be done about it.
344 if (value != attrIt->m_value) 413 if (value != attrIt->m_value)
345 return false; 414 return false;
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 m_contentMapText[CFilter::contentTypeSubdocument] = "SUBDOCUMENT"; 497 m_contentMapText[CFilter::contentTypeSubdocument] = "SUBDOCUMENT";
429 m_contentMapText[CFilter::contentTypeStyleSheet] = "STYLESHEET"; 498 m_contentMapText[CFilter::contentTypeStyleSheet] = "STYLESHEET";
430 m_contentMapText[CFilter::contentTypeXmlHttpRequest] = "XMLHTTPREQUEST"; 499 m_contentMapText[CFilter::contentTypeXmlHttpRequest] = "XMLHTTPREQUEST";
431 500
432 ClearFilters(); 501 ClearFilters();
433 } 502 }
434 503
435 504
436 bool CPluginFilter::AddFilterElementHide(CString filterText) 505 bool CPluginFilter::AddFilterElementHide(CString filterText)
437 { 506 {
438
439
440 DEBUG_FILTER("Input: " + filterText + " filterFile" + filterFile); 507 DEBUG_FILTER("Input: " + filterText + " filterFile" + filterFile);
441 508 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
442 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
443 { 509 {
444
445 CString filterString = filterText; 510 CString filterString = filterText;
446 // Create filter descriptor 511 // Create filter descriptor
447 std::auto_ptr<CFilterElementHide> filter; 512 std::auto_ptr<CFilterElementHide> filter;
448 513
449 CString wholeFilterString = filterString; 514 CString wholeFilterString = filterString;
450 wchar_t separatorChar; 515 wchar_t separatorChar;
451 do 516 do
452 { 517 {
453 int chunkEnd = filterText.FindOneOf(L"+>"); 518 int chunkEnd = filterText.FindOneOf(L"+>");
454 if (chunkEnd > 0) 519 if (chunkEnd > 0)
455 { 520 {
456 separatorChar = filterText.GetAt(chunkEnd); 521 separatorChar = filterText.GetAt(chunkEnd);
457 } 522 }
458 else 523 else
459 { 524 {
460 chunkEnd = filterText.GetLength(); 525 chunkEnd = filterText.GetLength();
461 separatorChar = L'\0'; 526 separatorChar = L'\0';
462 } 527 }
463 528
464 CString filterChunk = filterText.Left(chunkEnd).TrimRight(); 529 CString filterChunk = filterText.Left(chunkEnd).TrimRight();
465 std::auto_ptr<CFilterElementHide> filterParent(filter); 530 std::auto_ptr<CFilterElementHide> filterParent(filter);
466 531
467 filter.reset(new CFilterElementHide(filterChunk)); 532 filter.reset(new CFilterElementHide(filterChunk));
468 533
469 if (filterParent.get() != 0) 534 if (filterParent.get() != 0)
470 { 535 {
471 filter->m_predecessor.reset(filterParent.release()); 536 filter->m_predecessor.reset(filterParent.release());
472 } 537 }
473 538
474 if (separatorChar != L'\0') // complex selector 539 if (separatorChar != L'\0') // complex selector
475 { 540 {
476 filterText = filterText.Mid(chunkEnd + 1).TrimLeft(); 541 filterText = filterText.Mid(chunkEnd + 1).TrimLeft();
477 if (separatorChar == '+') 542 if (separatorChar == '+')
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 id = bstrId; 577 id = bstrId;
513 } 578 }
514 579
515 CString classNames; 580 CString classNames;
516 CComBSTR bstrClassNames; 581 CComBSTR bstrClassNames;
517 if (SUCCEEDED(pEl->get_className(&bstrClassNames)) && bstrClassNames) 582 if (SUCCEEDED(pEl->get_className(&bstrClassNames)) && bstrClassNames)
518 { 583 {
519 classNames = bstrClassNames; 584 classNames = bstrClassNames;
520 } 585 }
521 586
522 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); 587 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
523 { 588 {
524 // Search tag/id filters 589 // Search tag/id filters
525 if (!id.IsEmpty()) 590 if (!id.IsEmpty())
526 { 591 {
527 std::pair<TFilterElementHideTagsNamed::const_iterator, TFilterElementHideT agsNamed::const_iterator> idItEnum = 592 std::pair<TFilterElementHideTagsNamed::const_iterator, TFilterElementHideT agsNamed::const_iterator> idItEnum =
528 m_elementHideTagsId.equal_range(std::make_pair(tagCString, id)); 593 m_elementHideTagsId.equal_range(std::make_pair(tagCString, id));
529 for (TFilterElementHideTagsNamed::const_iterator idIt = idItEnum.first; id It != idItEnum.second; idIt ++) 594 for (TFilterElementHideTagsNamed::const_iterator idIt = idItEnum.first; id It != idItEnum.second; idIt ++)
530 { 595 {
531 if (idIt->second.IsMatchFilterElementHide(pEl)) 596 if (idIt->second.IsMatchFilterElementHide(pEl))
532 { 597 {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
614 } 679 }
615 680
616 bool CPluginFilter::LoadHideFilters(std::vector<std::wstring> filters) 681 bool CPluginFilter::LoadHideFilters(std::vector<std::wstring> filters)
617 { 682 {
618 ClearFilters(); 683 ClearFilters();
619 bool isRead = false; 684 bool isRead = false;
620 CPluginClient* client = CPluginClient::GetInstance(); 685 CPluginClient* client = CPluginClient::GetInstance();
621 686
622 // Parse hide string 687 // Parse hide string
623 int pos = 0; 688 int pos = 0;
624 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); 689 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
625 { 690 {
626 for (std::vector<std::wstring>::iterator it = filters.begin(); it < filters. end(); ++it) 691 for (std::vector<std::wstring>::iterator it = filters.begin(); it < filters. end(); ++it)
627 { 692 {
628 CString filter((*it).c_str()); 693 CString filter((*it).c_str());
629 // If the line is not commented out 694 // If the line is not commented out
630 if (!filter.Trim().IsEmpty() && filter.GetAt(0) != '!' && filter.GetAt(0) != '[') 695 if (!filter.Trim().IsEmpty() && filter.GetAt(0) != '!' && filter.GetAt(0) != '[')
631 { 696 {
632 int filterType = 0; 697 int filterType = 0;
633 698
634 // See http://adblockplus.org/en/filters for further documentation 699 // See http://adblockplus.org/en/filters for further documentation
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 CPluginDebug::DebugResultBlocking(type, srcCString, domain); 771 CPluginDebug::DebugResultBlocking(type, srcCString, domain);
707 #endif 772 #endif
708 } 773 }
709 return true; 774 return true;
710 } 775 }
711 #ifdef ENABLE_DEBUG_RESULT 776 #ifdef ENABLE_DEBUG_RESULT
712 CPluginDebug::DebugResultIgnoring(type, srcCString, domain); 777 CPluginDebug::DebugResultIgnoring(type, srcCString, domain);
713 #endif 778 #endif
714 return false; 779 return false;
715 } 780 }
OLDNEW
« no previous file with comments | « no previous file | src/plugin/PluginUtil.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld