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

Delta Between Two Patch Sets: src/plugin/PluginFilter.cpp

Issue 6567422169448448: Issue 119 - Switch to injecting CSS for element hiding (Closed)
Left Patch Set: Created Dec. 10, 2014, 5:12 p.m.
Right Patch Set: rename OnQuit Created Sept. 30, 2016, 3:25 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « src/plugin/PluginFilter.h ('k') | src/plugin/PluginTabBase.h » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2016 Eyeo GmbH
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
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/>.
16 */
17
1 #include "PluginStdAfx.h" 18 #include "PluginStdAfx.h"
2 19 #include "AdblockPlusClient.h"
3 #include "PluginFilter.h" 20 #include "PluginFilter.h"
4 #include "PluginSettings.h" 21 #include "PluginSettings.h"
5 #include "PluginClient.h"
6 #include "PluginClientFactory.h"
7 #include "PluginMutex.h" 22 #include "PluginMutex.h"
8 #include "PluginSettings.h" 23 #include "PluginSettings.h"
9 #include "PluginSystem.h" 24 #include "PluginSystem.h"
10 #include "PluginClass.h" 25 #include "PluginClass.h"
11 #include "mlang.h" 26 #include "mlang.h"
12
13 #include "..\shared\CriticalSection.h" 27 #include "..\shared\CriticalSection.h"
14 #include "..\shared\Utils.h" 28 #include "..\shared\Utils.h"
15 29 #include "..\shared\MsHTMLUtils.h"
16 30
17 // The filters are described at http://adblockplus.org/en/filters 31 // The filters are described at http://adblockplus.org/en/filters
18 32
19 static CriticalSection s_criticalSectionFilterMap; 33 static CriticalSection s_criticalSectionFilterMap;
20
21 namespace
22 {
23 struct GetHtmlElementAttributeResult
24 {
25 GetHtmlElementAttributeResult() : isAttributeFound(false)
26 {
27 }
28 std::wstring attributeValue;
29 bool isAttributeFound;
30 };
31
32 GetHtmlElementAttributeResult GetHtmlElementAttribute(IHTMLElement& htmlElemen t,
33 const ATL::CComBSTR& attributeName)
34 {
35 GetHtmlElementAttributeResult retValue;
36 ATL::CComVariant vAttr;
37 ATL::CComPtr<IHTMLElement4> htmlElement4;
38 if (FAILED(htmlElement.QueryInterface(&htmlElement4)) || !htmlElement4)
39 {
40 return retValue;
41 }
42 ATL::CComPtr<IHTMLDOMAttribute> attributeNode;
43 if (FAILED(htmlElement4->getAttributeNode(attributeName, &attributeNode)) || !attributeNode)
44 {
45 return retValue;
46 }
47 // we set that attribute found but it's not necessary that we can retrieve i ts value
48 retValue.isAttributeFound = true;
49 if (FAILED(attributeNode->get_nodeValue(&vAttr)))
50 {
51 return retValue;
52 }
53 if (vAttr.vt == VT_BSTR && vAttr.bstrVal)
54 {
55 retValue.attributeValue = vAttr.bstrVal;
56 }
57 else if (vAttr.vt == VT_I4)
58 {
59 retValue.attributeValue = std::to_wstring(vAttr.iVal);
60 }
61 return retValue;
62 }
63 }
64 34
65 // ============================================================================ 35 // ============================================================================
66 // CFilterElementHideAttrSelector 36 // CFilterElementHideAttrSelector
67 // ============================================================================ 37 // ============================================================================
68 38
69 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector() : m_type(TYPE_N ONE), m_pos(POS_NONE), m_bstrAttr(NULL) 39 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector() : m_type(TYPE_N ONE), m_pos(POS_NONE), m_bstrAttr(NULL)
70 { 40 {
71 } 41 }
72 42
73 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector(const CFilterElem entHideAttrSelector& filter) 43 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector(const CFilterElem entHideAttrSelector& filter)
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 m_predecessor = filter.m_predecessor; 218 m_predecessor = filter.m_predecessor;
249 } 219 }
250 220
251 221
252 // ============================================================================ 222 // ============================================================================
253 // CFilter 223 // CFilter
254 // ============================================================================ 224 // ============================================================================
255 225
256 CFilter::CFilter(const CFilter& filter) 226 CFilter::CFilter(const CFilter& filter)
257 { 227 {
258 m_contentType = filter.m_contentType;
259 m_filterType = filter.m_filterType; 228 m_filterType = filter.m_filterType;
260 229
261 m_isFirstParty = filter.m_isFirstParty; 230 m_isFirstParty = filter.m_isFirstParty;
262 m_isThirdParty = filter.m_isThirdParty; 231 m_isThirdParty = filter.m_isThirdParty;
263 232
264 m_isMatchCase = filter.m_isMatchCase; 233 m_isMatchCase = filter.m_isMatchCase;
265 m_isFromStart = filter.m_isFromStart; 234 m_isFromStart = filter.m_isFromStart;
266 m_isFromEnd = filter.m_isFromEnd; 235 m_isFromEnd = filter.m_isFromEnd;
267 236
268 m_filterText = filter.m_filterText; 237 m_filterText = filter.m_filterText;
269 238
270 m_hitCount = filter.m_hitCount; 239 m_hitCount = filter.m_hitCount;
271 } 240 }
272 241
273 242
274 CFilter::CFilter() : m_isMatchCase(false), m_isFirstParty(false), m_isThirdParty (false), m_contentType(CFilter::contentTypeAny), 243 CFilter::CFilter() : m_isMatchCase(false), m_isFirstParty(false),
244 m_isThirdParty(false),
275 m_isFromStart(false), m_isFromEnd(false), m_hitCount(0) 245 m_isFromStart(false), m_isFromEnd(false), m_hitCount(0)
276 { 246 {
277 } 247 }
278 248
279 249
280 bool CFilterElementHide::IsMatchFilterElementHide(IHTMLElement* pEl) const 250 bool CFilterElementHide::IsMatchFilterElementHide(IHTMLElement* pEl) const
281 { 251 {
282 HRESULT hr; 252 HRESULT hr;
283 253
284 if (!m_tagId.IsEmpty()) 254 if (!m_tagId.IsEmpty())
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 416
447 return true; 417 return true;
448 } 418 }
449 419
450 420
451 421
452 // ============================================================================ 422 // ============================================================================
453 // CPluginFilter 423 // CPluginFilter
454 // ============================================================================ 424 // ============================================================================
455 425
456 CPluginFilter::CPluginFilter(const CString& dataPath) : m_dataPath(dataPath)
457 {
458 m_contentMapText[CFilter::contentTypeDocument] = "DOCUMENT";
459 m_contentMapText[CFilter::contentTypeObject] = "OBJECT";
460 m_contentMapText[CFilter::contentTypeObjectSubrequest] = "OBJECT_SUBREQUEST";
461 m_contentMapText[CFilter::contentTypeImage] = "IMAGE";
462 m_contentMapText[CFilter::contentTypeScript] = "SCRIPT";
463 m_contentMapText[CFilter::contentTypeOther] = "OTHER";
464 m_contentMapText[CFilter::contentTypeUnknown] = "OTHER";
465 m_contentMapText[CFilter::contentTypeSubdocument] = "SUBDOCUMENT";
466 m_contentMapText[CFilter::contentTypeStyleSheet] = "STYLESHEET";
467 m_contentMapText[CFilter::contentTypeXmlHttpRequest] = "XMLHTTPREQUEST";
468
469 ClearFilters();
470 }
471
472
473 bool CPluginFilter::AddFilterElementHide(CString filterText) 426 bool CPluginFilter::AddFilterElementHide(CString filterText)
474 { 427 {
475 DEBUG_FILTER("Input: " + filterText + " filterFile" + filterFile); 428 DEBUG_FILTER("Input: " + filterText + " filterFile" + filterFile);
476 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); 429 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
477 { 430 {
478 CString filterString = filterText; 431 CString filterString = filterText;
479 // Create filter descriptor 432 // Create filter descriptor
480 std::auto_ptr<CFilterElementHide> filter; 433 std::auto_ptr<CFilterElementHide> filter;
481 434
482 CString wholeFilterString = filterString; 435 CString wholeFilterString = filterString;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 } 482 }
530 } 483 }
531 } while (separatorChar != '\0'); 484 } while (separatorChar != '\0');
532 } 485 }
533 486
534 return true; 487 return true;
535 } 488 }
536 489
537 bool CPluginFilter::IsElementHidden(const std::wstring& tag, IHTMLElement* pEl, const std::wstring& domain, const std::wstring& indent) const 490 bool CPluginFilter::IsElementHidden(const std::wstring& tag, IHTMLElement* pEl, const std::wstring& domain, const std::wstring& indent) const
538 { 491 {
539 CString tagCString = to_CString(tag); 492 CString tagCString = ToCString(tag);
540 493
541 CString id; 494 CString id;
542 CComBSTR bstrId; 495 CComBSTR bstrId;
543 if (SUCCEEDED(pEl->get_id(&bstrId)) && bstrId) 496 if (SUCCEEDED(pEl->get_id(&bstrId)) && bstrId)
544 { 497 {
545 id = bstrId; 498 id = bstrId;
546 } 499 }
547 500
548 CString classNames; 501 CString classNames;
549 CComBSTR bstrClassNames; 502 CComBSTR bstrClassNames;
550 if (SUCCEEDED(pEl->get_className(&bstrClassNames)) && bstrClassNames) 503 if (SUCCEEDED(pEl->get_className(&bstrClassNames)) && bstrClassNames)
551 { 504 {
552 classNames = bstrClassNames; 505 classNames = bstrClassNames;
553 } 506 }
554 507
555 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); 508 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
556 { 509 {
557 // Search tag/id filters 510 // Search tag/id filters
558 if (!id.IsEmpty()) 511 if (!id.IsEmpty())
559 { 512 {
560 std::pair<TFilterElementHideTagsNamed::const_iterator, TFilterElementHideT agsNamed::const_iterator> idItEnum = 513 std::pair<TFilterElementHideTagsNamed::const_iterator, TFilterElementHideT agsNamed::const_iterator> idItEnum =
561 m_elementHideTagsId.equal_range(std::make_pair(tagCString, id)); 514 m_elementHideTagsId.equal_range(std::make_pair(tagCString, id));
562 for (TFilterElementHideTagsNamed::const_iterator idIt = idItEnum.first; id It != idItEnum.second; idIt ++) 515 for (TFilterElementHideTagsNamed::const_iterator idIt = idItEnum.first; id It != idItEnum.second; idIt ++)
563 { 516 {
564 if (idIt->second.IsMatchFilterElementHide(pEl)) 517 if (idIt->second.IsMatchFilterElementHide(pEl))
565 { 518 {
566 #ifdef ENABLE_DEBUG_RESULT 519 #ifdef ENABLE_DEBUG_RESULT
567 DEBUG_HIDE_EL(indent + "HideEl::Found (tag/id) filter:" + idIt->second .m_filterText) 520 DEBUG_HIDE_EL(indent + "HideEl::Found (tag/id) filter:" + idIt->second .m_filterText)
568 CPluginDebug::DebugResultHiding(tagCString, "id:" + id, idIt->second .m_filterText); 521 CPluginDebug::DebugResultHiding(tag, L"id:" + ToWstring(id), ToWstri ng(idIt->second.m_filterText));
569 #endif 522 #endif
570 return true; 523 return true;
571 } 524 }
572 } 525 }
573 526
574 // Search general id 527 // Search general id
575 idItEnum = m_elementHideTagsId.equal_range(std::make_pair("", id)); 528 idItEnum = m_elementHideTagsId.equal_range(std::make_pair("", id));
576 for (TFilterElementHideTagsNamed::const_iterator idIt = idItEnum.first; id It != idItEnum.second; idIt ++) 529 for (TFilterElementHideTagsNamed::const_iterator idIt = idItEnum.first; id It != idItEnum.second; idIt ++)
577 { 530 {
578 if (idIt->second.IsMatchFilterElementHide(pEl)) 531 if (idIt->second.IsMatchFilterElementHide(pEl))
579 { 532 {
580 #ifdef ENABLE_DEBUG_RESULT 533 #ifdef ENABLE_DEBUG_RESULT
581 DEBUG_HIDE_EL(indent + "HideEl::Found (?/id) filter:" + idIt->second.m _filterText) 534 DEBUG_HIDE_EL(indent + "HideEl::Found (?/id) filter:" + idIt->second.m _filterText)
582 CPluginDebug::DebugResultHiding(tagCString, "id:" + id, idIt->second .m_filterText); 535 CPluginDebug::DebugResultHiding(tag, L"id:" + ToWstring(id), ToWstri ng(idIt->second.m_filterText));
583 #endif 536 #endif
584 return true; 537 return true;
585 } 538 }
586 } 539 }
587 } 540 }
588 541
589 // Search tag/className filters 542 // Search tag/className filters
590 if (!classNames.IsEmpty()) 543 if (!classNames.IsEmpty())
591 { 544 {
592 int pos = 0; 545 int pos = 0;
593 CString className = classNames.Tokenize(L" \t\n\r", pos); 546 CString className = classNames.Tokenize(L" \t\n\r", pos);
594 while (pos >= 0) 547 while (pos >= 0)
595 { 548 {
596 std::pair<TFilterElementHideTagsNamed::const_iterator, TFilterElementHid eTagsNamed::const_iterator> classItEnum = 549 std::pair<TFilterElementHideTagsNamed::const_iterator, TFilterElementHid eTagsNamed::const_iterator> classItEnum =
597 m_elementHideTagsClass.equal_range(std::make_pair(tagCString, classNam e)); 550 m_elementHideTagsClass.equal_range(std::make_pair(tagCString, classNam e));
598 551
599 for (TFilterElementHideTagsNamed::const_iterator classIt = classItEnum.f irst; classIt != classItEnum.second; ++classIt) 552 for (TFilterElementHideTagsNamed::const_iterator classIt = classItEnum.f irst; classIt != classItEnum.second; ++classIt)
600 { 553 {
601 if (classIt->second.IsMatchFilterElementHide(pEl)) 554 if (classIt->second.IsMatchFilterElementHide(pEl))
602 { 555 {
603 #ifdef ENABLE_DEBUG_RESULT 556 #ifdef ENABLE_DEBUG_RESULT
604 DEBUG_HIDE_EL(indent + "HideEl::Found (tag/class) filter:" + classIt ->second.m_filterText) 557 DEBUG_HIDE_EL(indent + "HideEl::Found (tag/class) filter:" + classIt ->second.m_filterText)
605 CPluginDebug::DebugResultHiding(tagCString, "class:" + className, classIt->second.m_filterText); 558 CPluginDebug::DebugResultHiding(tag, L"class:" + ToWstring(classNa me), ToWstring(classIt->second.m_filterText));
606 #endif 559 #endif
607 return true; 560 return true;
608 } 561 }
609 } 562 }
610 563
611 // Search general class name 564 // Search general class name
612 classItEnum = m_elementHideTagsClass.equal_range(std::make_pair("", clas sName)); 565 classItEnum = m_elementHideTagsClass.equal_range(std::make_pair("", clas sName));
613 for (TFilterElementHideTagsNamed::const_iterator classIt = classItEnum.f irst; classIt != classItEnum.second; ++ classIt) 566 for (TFilterElementHideTagsNamed::const_iterator classIt = classItEnum.f irst; classIt != classItEnum.second; ++ classIt)
614 { 567 {
615 if (classIt->second.IsMatchFilterElementHide(pEl)) 568 if (classIt->second.IsMatchFilterElementHide(pEl))
616 { 569 {
617 #ifdef ENABLE_DEBUG_RESULT 570 #ifdef ENABLE_DEBUG_RESULT
618 DEBUG_HIDE_EL(indent + "HideEl::Found (?/class) filter:" + classIt-> second.m_filterText) 571 DEBUG_HIDE_EL(indent + L"HideEl::Found (?/class) filter:" + ToWStrin g(classIt->second.m_filterText));
619 CPluginDebug::DebugResultHiding(tagCString, "class:" + className, classIt->second.m_filterText); 572 CPluginDebug::DebugResultHiding(tag, L"class:" + ToWstring(className ), ToWstring(classIt->second.m_filterText));
620 #endif 573 #endif
621 return true; 574 return true;
622 } 575 }
623 } 576 }
624 577
625 // Next class name 578 // Next class name
626 className = classNames.Tokenize(L" \t\n\r", pos); 579 className = classNames.Tokenize(L" \t\n\r", pos);
627 } 580 }
628 } 581 }
629 582
630 // Search tag filters 583 // Search tag filters
631 std::pair<TFilterElementHideTags::const_iterator, TFilterElementHideTags::co nst_iterator> tagItEnum 584 std::pair<TFilterElementHideTags::const_iterator, TFilterElementHideTags::co nst_iterator> tagItEnum
632 = m_elementHideTags.equal_range(tagCString); 585 = m_elementHideTags.equal_range(tagCString);
633 for (TFilterElementHideTags::const_iterator tagIt = tagItEnum.first; tagIt ! = tagItEnum.second; ++ tagIt) 586 for (TFilterElementHideTags::const_iterator tagIt = tagItEnum.first; tagIt ! = tagItEnum.second; ++ tagIt)
634 { 587 {
635 if (tagIt->second.IsMatchFilterElementHide(pEl)) 588 if (tagIt->second.IsMatchFilterElementHide(pEl))
636 { 589 {
637 #ifdef ENABLE_DEBUG_RESULT 590 #ifdef ENABLE_DEBUG_RESULT
638 DEBUG_HIDE_EL(indent + "HideEl::Found (tag) filter:" + tagIt->second.m_f ilterText) 591 DEBUG_HIDE_EL(indent + "HideEl::Found (tag) filter:" + tagIt->second.m_f ilterText)
639 CPluginDebug::DebugResultHiding(tagCString, "-", tagIt->second.m_filte rText); 592 CPluginDebug::DebugResultHiding(tag, L"-", ToWstring(tagIt->second.m_f ilterText));
640 #endif 593 #endif
641 return true; 594 return true;
642 } 595 }
643 } 596 }
644 } 597 }
645 598
646 return false; 599 return false;
647 } 600 }
648 601
649 bool CPluginFilter::LoadHideFilters(const std::vector<std::wstring>& filters) 602 CPluginFilter::CPluginFilter(const std::vector<std::wstring>& filters)
650 { 603 {
651 ClearFilters();
652 m_hideFilters = filters; 604 m_hideFilters = filters;
653 bool isRead = false;
654 CPluginClient* client = CPluginClient::GetInstance(); 605 CPluginClient* client = CPluginClient::GetInstance();
655 606
656 // Parse hide string 607 // Parse hide string
657 int pos = 0; 608 int pos = 0;
658 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); 609 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
659 { 610 {
660 for (std::vector<std::wstring>::const_iterator it = filters.begin(); it < fi lters.end(); ++it) 611 for (auto it = filters.begin(); it < filters.end(); ++it)
661 { 612 {
662 CString filter((*it).c_str()); 613 CString filter((*it).c_str());
663 // If the line is not commented out 614 // If the line is not commented out
664 if (!filter.Trim().IsEmpty() && filter.GetAt(0) != '!' && filter.GetAt(0) != '[') 615 if (!filter.Trim().IsEmpty() && filter.GetAt(0) != '!' && filter.GetAt(0) != '[')
665 { 616 {
666 int filterType = 0; 617 int filterType = 0;
667 618
668 // See http://adblockplus.org/en/filters for further documentation 619 // See http://adblockplus.org/en/filters for further documentation
669 620
670 try 621 try
671 { 622 {
672 AddFilterElementHide(filter); 623 AddFilterElementHide(filter);
673 } 624 }
674 catch(...) 625 catch(...)
675 { 626 {
676 #ifdef ENABLE_DEBUG_RESULT 627 #ifdef ENABLE_DEBUG_RESULT
677 CPluginDebug::DebugResult(L"Error loading hide filter: " + filter); 628 CPluginDebug::DebugResult(L"Error loading hide filter: " + ToWstring(f ilter));
678 #endif 629 #endif
679 } 630 }
680 } 631 }
681 } 632 }
682 } 633 }
683
684 return isRead;
685 }
686
687 void CPluginFilter::ClearFilters()
688 {
689 // Clear filter maps
690 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
691 {
692 for (int i = 0; i < 2; i++)
693 {
694 for (int j = 0; j < 2; j++)
695 {
696 m_filterMap[i][j].clear();
697 }
698 m_filterMapDefault[i].clear();
699 }
700
701 m_elementHideTags.clear();
702 m_elementHideTagsId.clear();
703 m_elementHideTagsClass.clear();
704 m_hideFilters.clear();
705 }
706 }
707
708 bool CPluginFilter::ShouldBlock(const std::wstring& src, int contentType, const std::wstring& domain, bool addDebug) const
709 {
710 CString srcCString = to_CString(src);
711
712 // We should not block the empty string, so all filtering does not make sense
713 // Therefore we just return
714 if (srcCString.Trim().IsEmpty())
715 {
716 return false;
717 }
718
719 CPluginSettings* settings = CPluginSettings::GetInstance();
720
721 CString type;
722 if (addDebug)
723 {
724 type = "OTHER";
725
726 std::map<int,CString>::const_iterator it = m_contentMapText.find(contentType );
727 if (it != m_contentMapText.end())
728 {
729 type = it->second;
730 }
731 }
732
733 CPluginClient* client = CPluginClient::GetInstance();
734 if (client->Matches(to_wstring(srcCString), to_wstring(type), domain))
735 {
736 if (addDebug)
737 {
738 DEBUG_FILTER("Filter::ShouldBlock " + type + " YES")
739
740 #ifdef ENABLE_DEBUG_RESULT
741 CPluginDebug::DebugResultBlocking(type, srcCString, domain);
742 #endif
743 }
744 return true;
745 }
746 #ifdef ENABLE_DEBUG_RESULT
747 CPluginDebug::DebugResultIgnoring(type, srcCString, domain);
748 #endif
749 return false;
750 }
751
752 const std::vector<std::wstring>& CPluginFilter::getHideFilters() const
753 {
754 DWORD res = WaitForSingleObject(hideFiltersLoadedEvent, ENGINE_STARTUP_TIMEOUT );
Oleksandr 2015/02/04 20:59:57 It's hard to understand this from the scattered re
sergei 2015/04/13 08:06:58 `hideFiltersLoadedEvent` is not introduced in thes
755 return m_hideFilters;
756 } 634 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld