| 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 |