| LEFT | RIGHT | 
|---|
| 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; | 
|  | 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 } | 
| 19 | 64 | 
| 20 // ============================================================================ | 65 // ============================================================================ | 
| 21 // CFilterElementHideAttrSelector | 66 // CFilterElementHideAttrSelector | 
| 22 // ============================================================================ | 67 // ============================================================================ | 
| 23 | 68 | 
| 24 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector() : m_type(TYPE_N
     ONE), m_pos(POS_NONE), m_bstrAttr(NULL) | 69 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector() : m_type(TYPE_N
     ONE), m_pos(POS_NONE), m_bstrAttr(NULL) | 
| 25 { | 70 { | 
| 26 } | 71 } | 
| 27 | 72 | 
| 28 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector(const CFilterElem
     entHideAttrSelector& filter) | 73 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector(const CFilterElem
     entHideAttrSelector& filter) | 
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 265       } | 310       } | 
| 266       if (!foundMatch) | 311       if (!foundMatch) | 
| 267       { | 312       { | 
| 268         return false; | 313         return false; | 
| 269       } | 314       } | 
| 270     } | 315     } | 
| 271   } | 316   } | 
| 272   if (!m_tag.IsEmpty()) | 317   if (!m_tag.IsEmpty()) | 
| 273   { | 318   { | 
| 274     CComBSTR tagName; | 319     CComBSTR tagName; | 
|  | 320     hr = pEl->get_tagName(&tagName); | 
| 275     tagName.ToLower(); | 321     tagName.ToLower(); | 
| 276     hr = pEl->get_tagName(&tagName); |  | 
| 277     if ((hr != S_OK) || (tagName != CComBSTR(m_tag))) | 322     if ((hr != S_OK) || (tagName != CComBSTR(m_tag))) | 
| 278     { | 323     { | 
| 279       return false; | 324       return false; | 
| 280     } | 325     } | 
| 281   } | 326   } | 
| 282 | 327 | 
| 283   // Check attributes | 328   // Check attributes | 
| 284   for (std::vector<CFilterElementHideAttrSelector>::const_iterator attrIt = m_at
     tributeSelectors.begin(); | 329   for (std::vector<CFilterElementHideAttrSelector>::const_iterator attrIt = m_at
     tributeSelectors.begin(); | 
| 285         attrIt != m_attributeSelectors.end(); ++ attrIt) | 330         attrIt != m_attributeSelectors.end(); ++ attrIt) | 
| 286   { | 331   { | 
| 287     CString value; | 332     ATL::CString value; | 
| 288     bool attrFound = false; | 333     bool attrFound = false; | 
| 289     if (attrIt->m_type == CFilterElementHideAttrType::STYLE) | 334     if (attrIt->m_type == CFilterElementHideAttrType::STYLE) | 
| 290     { | 335     { | 
| 291       CComPtr<IHTMLStyle> pStyle; | 336       CComPtr<IHTMLStyle> pStyle; | 
| 292       if (SUCCEEDED(pEl->get_style(&pStyle)) && pStyle) | 337       if (SUCCEEDED(pEl->get_style(&pStyle)) && pStyle) | 
| 293       { | 338       { | 
| 294         CComBSTR bstrStyle; | 339         CComBSTR bstrStyle; | 
| 295 | 340 | 
| 296         if (SUCCEEDED(pStyle->get_cssText(&bstrStyle)) && bstrStyle) | 341         if (SUCCEEDED(pStyle->get_cssText(&bstrStyle)) && bstrStyle) | 
| 297         { | 342         { | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 312     } | 357     } | 
| 313     else if (attrIt->m_type == CFilterElementHideAttrType::ID) | 358     else if (attrIt->m_type == CFilterElementHideAttrType::ID) | 
| 314     { | 359     { | 
| 315       CComBSTR bstrId; | 360       CComBSTR bstrId; | 
| 316       if (SUCCEEDED(pEl->get_id(&bstrId)) && bstrId) | 361       if (SUCCEEDED(pEl->get_id(&bstrId)) && bstrId) | 
| 317       { | 362       { | 
| 318         value = bstrId; | 363         value = bstrId; | 
| 319         attrFound = true; | 364         attrFound = true; | 
| 320       } | 365       } | 
| 321     } | 366     } | 
| 322     else | 367     else | 
| 323     { | 368     { | 
| 324       CComVariant vAttr; | 369       auto attributeValue = GetHtmlElementAttribute(*pEl, attrIt->m_bstrAttr); | 
| 325       if (SUCCEEDED(pEl->getAttribute(attrIt->m_bstrAttr, 0, &vAttr))) | 370       if (attrFound = attributeValue.isAttributeFound) | 
| 326       { | 371       { | 
| 327         attrFound = true; | 372         value = ToCString(attributeValue.attributeValue); | 
| 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       } | 373       } | 
| 337     } | 374     } | 
| 338 | 375 | 
| 339     if (attrFound) | 376     if (attrFound) | 
| 340     { | 377     { | 
| 341       if (attrIt->m_pos == CFilterElementHideAttrPos::EXACT) | 378       if (attrIt->m_pos == CFilterElementHideAttrPos::EXACT) | 
| 342       { | 379       { | 
| 343         // TODO: IE rearranges the style attribute completely. Figure out if any
     thing can be done about it. | 380         // TODO: IE rearranges the style attribute completely. Figure out if any
     thing can be done about it. | 
| 344         if (value != attrIt->m_value) | 381         if (value != attrIt->m_value) | 
| 345           return false; | 382           return false; | 
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 413 | 450 | 
| 414 | 451 | 
| 415 // ============================================================================ | 452 // ============================================================================ | 
| 416 // CPluginFilter | 453 // CPluginFilter | 
| 417 // ============================================================================ | 454 // ============================================================================ | 
| 418 | 455 | 
| 419 CPluginFilter::CPluginFilter(const CString& dataPath) : m_dataPath(dataPath) | 456 CPluginFilter::CPluginFilter(const CString& dataPath) : m_dataPath(dataPath) | 
| 420 { | 457 { | 
| 421   m_contentMapText[CFilter::contentTypeDocument] = "DOCUMENT"; | 458   m_contentMapText[CFilter::contentTypeDocument] = "DOCUMENT"; | 
| 422   m_contentMapText[CFilter::contentTypeObject] = "OBJECT"; | 459   m_contentMapText[CFilter::contentTypeObject] = "OBJECT"; | 
|  | 460   m_contentMapText[CFilter::contentTypeObjectSubrequest] = "OBJECT_SUBREQUEST"; | 
| 423   m_contentMapText[CFilter::contentTypeImage] = "IMAGE"; | 461   m_contentMapText[CFilter::contentTypeImage] = "IMAGE"; | 
| 424   m_contentMapText[CFilter::contentTypeScript] = "SCRIPT"; | 462   m_contentMapText[CFilter::contentTypeScript] = "SCRIPT"; | 
| 425   m_contentMapText[CFilter::contentTypeOther] = "OTHER"; | 463   m_contentMapText[CFilter::contentTypeOther] = "OTHER"; | 
| 426   m_contentMapText[CFilter::contentTypeUnknown] = "OTHER"; | 464   m_contentMapText[CFilter::contentTypeUnknown] = "OTHER"; | 
| 427   m_contentMapText[CFilter::contentTypeSubdocument] = "SUBDOCUMENT"; | 465   m_contentMapText[CFilter::contentTypeSubdocument] = "SUBDOCUMENT"; | 
| 428   m_contentMapText[CFilter::contentTypeStyleSheet] = "STYLESHEET"; | 466   m_contentMapText[CFilter::contentTypeStyleSheet] = "STYLESHEET"; | 
| 429   m_contentMapText[CFilter::contentTypeXmlHttpRequest] = "XMLHTTPREQUEST"; | 467   m_contentMapText[CFilter::contentTypeXmlHttpRequest] = "XMLHTTPREQUEST"; | 
| 430 | 468 | 
| 431   ClearFilters(); | 469   ClearFilters(); | 
| 432 } | 470 } | 
| 433 | 471 | 
| 434 | 472 | 
| 435 bool CPluginFilter::AddFilterElementHide(CString filterText) | 473 bool CPluginFilter::AddFilterElementHide(CString filterText) | 
| 436 { | 474 { | 
| 437 |  | 
| 438 |  | 
| 439   DEBUG_FILTER("Input: " + filterText + " filterFile" + filterFile); | 475   DEBUG_FILTER("Input: " + filterText + " filterFile" + filterFile); | 
| 440 | 476   CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 
| 441   CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 477   { | 
| 442   { |  | 
| 443 |  | 
| 444     CString filterString  = filterText; | 478     CString filterString  = filterText; | 
| 445     // Create filter descriptor | 479     // Create filter descriptor | 
| 446     std::auto_ptr<CFilterElementHide> filter; | 480     std::auto_ptr<CFilterElementHide> filter; | 
| 447 | 481 | 
| 448     CString wholeFilterString = filterString; | 482     CString wholeFilterString = filterString; | 
| 449     wchar_t separatorChar; | 483     wchar_t separatorChar; | 
| 450     do | 484     do | 
| 451     { | 485     { | 
| 452       int chunkEnd = filterText.FindOneOf(L"+>"); | 486       int chunkEnd = filterText.FindOneOf(L"+>"); | 
| 453       if (chunkEnd > 0) | 487       if (chunkEnd > 0) | 
| 454       { | 488       { | 
| 455         separatorChar = filterText.GetAt(chunkEnd); | 489         separatorChar = filterText.GetAt(chunkEnd); | 
| 456       } | 490       } | 
| 457       else | 491       else | 
| 458       { | 492       { | 
| 459         chunkEnd = filterText.GetLength(); | 493         chunkEnd = filterText.GetLength(); | 
| 460         separatorChar = L'\0'; | 494         separatorChar = L'\0'; | 
| 461       } | 495       } | 
| 462 | 496 | 
| 463       CString filterChunk = filterText.Left(chunkEnd).TrimRight(); | 497       CString filterChunk = filterText.Left(chunkEnd).TrimRight(); | 
| 464       std::auto_ptr<CFilterElementHide> filterParent(filter); | 498       std::auto_ptr<CFilterElementHide> filterParent(filter); | 
| 465 | 499 | 
| 466       filter.reset(new CFilterElementHide(filterChunk)); | 500       filter.reset(new CFilterElementHide(filterChunk)); | 
| 467 | 501 | 
| 468       if (filterParent.get() != 0) | 502       if (filterParent.get() != 0) | 
| 469       { | 503       { | 
| 470         filter->m_predecessor.reset(filterParent.release()); | 504         filter->m_predecessor.reset(filterParent.release()); | 
| 471       } | 505       } | 
| 472 | 506 | 
| 473       if (separatorChar != L'\0') // complex selector | 507       if (separatorChar != L'\0') // complex selector | 
| 474       { | 508       { | 
| 475         filterText = filterText.Mid(chunkEnd + 1).TrimLeft(); | 509         filterText = filterText.Mid(chunkEnd + 1).TrimLeft(); | 
| 476         if (separatorChar == '+') | 510         if (separatorChar == '+') | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 511     id = bstrId; | 545     id = bstrId; | 
| 512   } | 546   } | 
| 513 | 547 | 
| 514   CString classNames; | 548   CString classNames; | 
| 515   CComBSTR bstrClassNames; | 549   CComBSTR bstrClassNames; | 
| 516   if (SUCCEEDED(pEl->get_className(&bstrClassNames)) && bstrClassNames) | 550   if (SUCCEEDED(pEl->get_className(&bstrClassNames)) && bstrClassNames) | 
| 517   { | 551   { | 
| 518     classNames = bstrClassNames; | 552     classNames = bstrClassNames; | 
| 519   } | 553   } | 
| 520 | 554 | 
| 521   CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 555   CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 
| 522   { | 556   { | 
| 523     // Search tag/id filters | 557     // Search tag/id filters | 
| 524     if (!id.IsEmpty()) | 558     if (!id.IsEmpty()) | 
| 525     { | 559     { | 
| 526       std::pair<TFilterElementHideTagsNamed::const_iterator, TFilterElementHideT
     agsNamed::const_iterator> idItEnum = | 560       std::pair<TFilterElementHideTagsNamed::const_iterator, TFilterElementHideT
     agsNamed::const_iterator> idItEnum = | 
| 527         m_elementHideTagsId.equal_range(std::make_pair(tagCString, id)); | 561         m_elementHideTagsId.equal_range(std::make_pair(tagCString, id)); | 
| 528       for (TFilterElementHideTagsNamed::const_iterator idIt = idItEnum.first; id
     It != idItEnum.second; idIt ++) | 562       for (TFilterElementHideTagsNamed::const_iterator idIt = idItEnum.first; id
     It != idItEnum.second; idIt ++) | 
| 529       { | 563       { | 
| 530         if (idIt->second.IsMatchFilterElementHide(pEl)) | 564         if (idIt->second.IsMatchFilterElementHide(pEl)) | 
| 531         { | 565         { | 
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 613 } | 647 } | 
| 614 | 648 | 
| 615 bool CPluginFilter::LoadHideFilters(std::vector<std::wstring> filters) | 649 bool CPluginFilter::LoadHideFilters(std::vector<std::wstring> filters) | 
| 616 { | 650 { | 
| 617   ClearFilters(); | 651   ClearFilters(); | 
| 618   bool isRead = false; | 652   bool isRead = false; | 
| 619   CPluginClient* client = CPluginClient::GetInstance(); | 653   CPluginClient* client = CPluginClient::GetInstance(); | 
| 620 | 654 | 
| 621   // Parse hide string | 655   // Parse hide string | 
| 622   int pos = 0; | 656   int pos = 0; | 
| 623   CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 657   CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 
| 624   { | 658   { | 
| 625     for (std::vector<std::wstring>::iterator it = filters.begin(); it < filters.
     end(); ++it) | 659     for (std::vector<std::wstring>::iterator it = filters.begin(); it < filters.
     end(); ++it) | 
| 626     { | 660     { | 
| 627       CString filter((*it).c_str()); | 661       CString filter((*it).c_str()); | 
| 628       // If the line is not commented out | 662       // If the line is not commented out | 
| 629       if (!filter.Trim().IsEmpty() && filter.GetAt(0) != '!' && filter.GetAt(0) 
     != '[') | 663       if (!filter.Trim().IsEmpty() && filter.GetAt(0) != '!' && filter.GetAt(0) 
     != '[') | 
| 630       { | 664       { | 
| 631         int filterType = 0; | 665         int filterType = 0; | 
| 632 | 666 | 
| 633         // See http://adblockplus.org/en/filters for further documentation | 667         // See http://adblockplus.org/en/filters for further documentation | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 645       } | 679       } | 
| 646     } | 680     } | 
| 647   } | 681   } | 
| 648 | 682 | 
| 649   return isRead; | 683   return isRead; | 
| 650 } | 684 } | 
| 651 | 685 | 
| 652 void CPluginFilter::ClearFilters() | 686 void CPluginFilter::ClearFilters() | 
| 653 { | 687 { | 
| 654   // Clear filter maps | 688   // Clear filter maps | 
| 655   CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 689   CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 
| 656   { | 690   { | 
| 657     for (int i = 0; i < 2; i++) | 691     for (int i = 0; i < 2; i++) | 
| 658     { | 692     { | 
| 659       for (int j = 0; j < 2; j++) | 693       for (int j = 0; j < 2; j++) | 
| 660       { | 694       { | 
| 661         m_filterMap[i][j].clear(); | 695         m_filterMap[i][j].clear(); | 
| 662       } | 696       } | 
| 663       m_filterMapDefault[i].clear(); | 697       m_filterMapDefault[i].clear(); | 
| 664     } | 698     } | 
| 665 | 699 | 
| 666     m_elementHideTags.clear(); | 700     m_elementHideTags.clear(); | 
| 667     m_elementHideTagsId.clear(); | 701     m_elementHideTagsId.clear(); | 
| 668     m_elementHideTagsClass.clear(); | 702     m_elementHideTagsClass.clear(); | 
| 669   } | 703   } | 
| 670 } | 704 } | 
| 671 | 705 | 
| 672 bool CPluginFilter::ShouldBlock(const std::wstring& src, int contentType, const 
     std::wstring& domain, bool addDebug) const | 706 bool CPluginFilter::ShouldBlock(const std::wstring& src, int contentType, const 
     std::wstring& domain, bool addDebug) const | 
| 673 { | 707 { | 
| 674   CString srcCString = ToCString(src); | 708   std::wstring srcTrimmed = TrimString(src); | 
| 675   srcCString.Trim(); |  | 
| 676   std::wstring srcTrimmed = ToWstring(srcCString); |  | 
| 677 | 709 | 
| 678   // We should not block the empty string, so all filtering does not make sense | 710   // We should not block the empty string, so all filtering does not make sense | 
| 679   // Therefore we just return | 711   // Therefore we just return | 
| 680   if (srcTrimmed.empty()) | 712   if (srcTrimmed.empty()) | 
| 681   { | 713   { | 
| 682     return false; | 714     return false; | 
| 683   } | 715   } | 
| 684   CPluginSettings* settings = CPluginSettings::GetInstance(); | 716   CPluginSettings* settings = CPluginSettings::GetInstance(); | 
| 685 | 717 | 
| 686   CString type; | 718   CString type; | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 701     if (addDebug) | 733     if (addDebug) | 
| 702     { | 734     { | 
| 703       DEBUG_FILTER("Filter::ShouldBlock " + type + " YES") | 735       DEBUG_FILTER("Filter::ShouldBlock " + type + " YES") | 
| 704 | 736 | 
| 705 #ifdef ENABLE_DEBUG_RESULT | 737 #ifdef ENABLE_DEBUG_RESULT | 
| 706         CPluginDebug::DebugResultBlocking(type, srcTrimmed, domain); | 738         CPluginDebug::DebugResultBlocking(type, srcTrimmed, domain); | 
| 707 #endif | 739 #endif | 
| 708     } | 740     } | 
| 709     return true; | 741     return true; | 
| 710   } | 742   } | 
|  | 743 #ifdef ENABLE_DEBUG_RESULT | 
|  | 744   CPluginDebug::DebugResultIgnoring(type, srcTrimmed, domain); | 
|  | 745 #endif | 
| 711   return false; | 746   return false; | 
| 712 } | 747 } | 
| LEFT | RIGHT | 
|---|