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

Unified Diff: src/plugin/PluginFilter.cpp

Issue 5316782940225536: Issue 1557 - Update to the recent libadblockplus to reduce additional updates in the logic later. (Closed)
Patch Set: link addon with libadblockplus Created Jan. 29, 2015, 4:05 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/plugin/PluginFilter.cpp
diff --git a/src/plugin/PluginFilter.cpp b/src/plugin/PluginFilter.cpp
index 269f3a2214728ba6cd1c8c9f7fae892bff21ea12..46af181bf5b3cb553ab8a389a22341a4c35b4bee 100644
--- a/src/plugin/PluginFilter.cpp
+++ b/src/plugin/PluginFilter.cpp
@@ -15,750 +15,731 @@
* along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "PluginStdAfx.h"
-
-#include "PluginFilter.h"
-#include "PluginSettings.h"
-#include "PluginClient.h"
-#include "PluginClientFactory.h"
-#include "PluginMutex.h"
-#include "PluginSettings.h"
-#include "PluginSystem.h"
-#include "PluginClass.h"
-#include "mlang.h"
-
-#include "..\shared\CriticalSection.h"
-#include "..\shared\Utils.h"
-
-
-// The filters are described at http://adblockplus.org/en/filters
-
-static CriticalSection s_criticalSectionFilterMap;
-
-namespace
-{
- struct GetHtmlElementAttributeResult
- {
- GetHtmlElementAttributeResult() : isAttributeFound(false)
- {
- }
- std::wstring attributeValue;
- bool isAttributeFound;
- };
-
- GetHtmlElementAttributeResult GetHtmlElementAttribute(IHTMLElement& htmlElement,
- const ATL::CComBSTR& attributeName)
- {
- GetHtmlElementAttributeResult retValue;
- ATL::CComVariant vAttr;
- ATL::CComPtr<IHTMLElement4> htmlElement4;
- if (FAILED(htmlElement.QueryInterface(&htmlElement4)) || !htmlElement4)
- {
- return retValue;
- }
- ATL::CComPtr<IHTMLDOMAttribute> attributeNode;
- if (FAILED(htmlElement4->getAttributeNode(attributeName, &attributeNode)) || !attributeNode)
- {
- return retValue;
- }
- // we set that attribute found but it's not necessary that we can retrieve its value
- retValue.isAttributeFound = true;
- if (FAILED(attributeNode->get_nodeValue(&vAttr)))
- {
- return retValue;
- }
- if (vAttr.vt == VT_BSTR && vAttr.bstrVal)
- {
- retValue.attributeValue = vAttr.bstrVal;
- }
- else if (vAttr.vt == VT_I4)
- {
- retValue.attributeValue = std::to_wstring(vAttr.iVal);
- }
- return retValue;
- }
-}
-
-// ============================================================================
-// CFilterElementHideAttrSelector
-// ============================================================================
-
-CFilterElementHideAttrSelector::CFilterElementHideAttrSelector() : m_type(TYPE_NONE), m_pos(POS_NONE), m_bstrAttr(NULL)
-{
-}
-
-CFilterElementHideAttrSelector::CFilterElementHideAttrSelector(const CFilterElementHideAttrSelector& filter)
-{
- m_type = filter.m_type;
- m_pos = filter.m_pos;
- m_bstrAttr = filter.m_bstrAttr;
-
- m_value = filter.m_value;
-}
-
-CFilterElementHideAttrSelector::~CFilterElementHideAttrSelector()
-{
-}
-
-
-// ============================================================================
-// CFilterElementHide
-// ============================================================================
-
-CFilterElementHide::CFilterElementHide(const CString& filterText) : m_filterText(filterText), m_type(ETraverserComplexType::TRAVERSER_TYPE_ERROR)
-{
- // Find tag name, class or any (*)
- CString filterString = filterText;
-
- wchar_t firstTag = filterString.GetAt(0);
- // Any tag
- if (firstTag == '*')
- {
- filterString = filterString.Mid(1);
- }
- // Any tag (implicitely)
- else if (firstTag == '[' || firstTag == '.' || firstTag == '#')
- {
- }
- // Real tag
- else if (isalnum(firstTag))
- {
- //TODO: Add support for descendant selectors
- int pos = filterString.FindOneOf(L".#[(");
-
- if (pos < 0)
- pos = filterString.GetLength();
- m_tag = filterString.Left(pos).MakeLower();
-
- filterString = filterString.Mid(pos);
- }
- // Error
- else
- {
- DEBUG_FILTER("Filter::Error parsing selector:" + filterText + " (invalid tag)");
- throw std::runtime_error(CStringA("Filter::Error parsing selector:" + filterText + " (invalid tag)").GetString());
- }
-
- // Find Id and class name
-
- if (!filterString.IsEmpty())
- {
- wchar_t firstId = filterString.GetAt(0);
-
- // Id
- if (firstId == '#')
- {
- int pos = filterString.Find('[');
- if (pos < 0)
- {
- pos = filterString.GetLength();
- }
- m_tagId = filterString.Mid(1, pos - 1);
- filterString = filterString.Mid(pos);
- pos = m_tagId.Find(L".");
- if (pos > 0)
- {
- m_tagClassName = m_tagId.Mid(pos + 1);
- m_tagId = m_tagId.Left(pos);
- }
- }
- // Class name
- else if (firstId == '.')
- {
- int pos = filterString.Find('[');
- if (pos < 0)
- {
- pos = filterString.GetLength();
- }
- m_tagClassName = filterString.Mid(1, pos - 1);
- filterString = filterString.Mid(pos);
- }
- }
-
- char chAttrStart = '[';
- char chAttrEnd = ']';
-
- while (!filterString.IsEmpty())
- {
- if (filterString.GetAt(0) != chAttrStart)
- {
- DEBUG_FILTER("Filter::Error parsing selector:" + filterText + " (more data)");
- throw std::runtime_error(CStringA("Filter::Error parsing selector:" + filterText + " (more data)").GetString());
- }
- int endPos = filterString.Find(']') ;
- if (endPos < 0)
- {
- DEBUG_FILTER("Filter::Error parsing selector:" + filterText + " (more data)");
- throw std::runtime_error(CStringA("Filter::Error parsing selector:" + filterText + " (more data)").GetString());
- }
-
- CFilterElementHideAttrSelector attrSelector;
-
- CString arg = filterString.Mid(1, endPos - 1);
- filterString = filterString.Mid(endPos + 1);
-
- int delimiterPos = arg.Find('=');
- if (delimiterPos > 0)
- {
- attrSelector.m_value = arg.Mid(delimiterPos + 1);
- if (attrSelector.m_value.GetLength() >= 2 && attrSelector.m_value.GetAt(0) == '\"' && attrSelector.m_value.GetAt(attrSelector.m_value.GetLength() - 1) == '\"')
- {
- attrSelector.m_value = attrSelector.m_value.Mid(1, attrSelector.m_value.GetLength() - 2);
- }
-
- if (arg.GetAt(delimiterPos - 1) == '^')
- {
- attrSelector.m_bstrAttr = arg.Left(delimiterPos - 1);
- attrSelector.m_pos = CFilterElementHideAttrPos::STARTING;
- }
- else if (arg.GetAt(delimiterPos - 1) == '*')
- {
- attrSelector.m_bstrAttr = arg.Left(delimiterPos - 1);
- attrSelector.m_pos = CFilterElementHideAttrPos::ANYWHERE;
- }
- else if (arg.GetAt(delimiterPos - 1) == '$')
- {
- attrSelector.m_bstrAttr = arg.Left(delimiterPos - 1);
- attrSelector.m_pos = CFilterElementHideAttrPos::ENDING;
- }
- else
- {
- attrSelector.m_bstrAttr = arg.Left(delimiterPos);
- attrSelector.m_pos = CFilterElementHideAttrPos::EXACT;
- }
- }
- CString tag = attrSelector.m_bstrAttr;
- if (tag == "style")
- {
- attrSelector.m_type = CFilterElementHideAttrType::STYLE;
- attrSelector.m_value.MakeLower();
- }
- else if (tag == "id")
- {
- attrSelector.m_type = CFilterElementHideAttrType::ID;
- }
- else if (tag == "class")
- {
- attrSelector.m_type = CFilterElementHideAttrType::CLASS;
- }
- m_attributeSelectors.push_back(attrSelector);
-
- }
-
- // End check
- if (!filterString.IsEmpty())
- {
- DEBUG_FILTER("Filter::Error parsing selector:" + filterFile + "/" + filterText + " (more data)")
- throw new std::runtime_error(CStringA("Filter::Error parsing selector:" + filterText + " (more data)").GetString());
- }
-}
-
-CFilterElementHide::CFilterElementHide(const CFilterElementHide& filter)
-{
- m_filterText = filter.m_filterText;
-
- m_tagId = filter.m_tagId;
- m_tagClassName = filter.m_tagClassName;
-
- m_attributeSelectors = filter.m_attributeSelectors;
-
- m_predecessor = filter.m_predecessor;
-}
-
-
-// ============================================================================
-// CFilter
-// ============================================================================
-
-CFilter::CFilter(const CFilter& filter)
-{
- m_contentType = filter.m_contentType;
- m_filterType = filter.m_filterType;
-
- m_isFirstParty = filter.m_isFirstParty;
- m_isThirdParty = filter.m_isThirdParty;
-
- m_isMatchCase = filter.m_isMatchCase;
- m_isFromStart = filter.m_isFromStart;
- m_isFromEnd = filter.m_isFromEnd;
-
- m_filterText = filter.m_filterText;
-
- m_hitCount = filter.m_hitCount;
-}
-
-
-CFilter::CFilter() : m_isMatchCase(false), m_isFirstParty(false), m_isThirdParty(false), m_contentType(CFilter::contentTypeAny),
- m_isFromStart(false), m_isFromEnd(false), m_hitCount(0)
-{
-}
-
-
-bool CFilterElementHide::IsMatchFilterElementHide(IHTMLElement* pEl) const
-{
- HRESULT hr;
-
- if (!m_tagId.IsEmpty())
- {
- CComBSTR id;
- hr = pEl->get_id(&id);
- if ((hr != S_OK) || (id != CComBSTR(m_tagId)))
- {
- return false;
- }
- }
- if (!m_tagClassName.IsEmpty())
- {
- CComBSTR classNameBSTR;
- hr = pEl->get_className(&classNameBSTR);
- if (hr == S_OK)
- {
- CString className = classNameBSTR;
- int start = 0;
- CString specificClass;
- bool foundMatch = false;
- while ((specificClass = className.Tokenize(L" ", start)) != L"")
- {
- // TODO: Consider case of multiple classes. (m_tagClassName can be something like "foo.bar")
- if (specificClass == m_tagClassName)
- {
- foundMatch = true;
- }
- }
- if (!foundMatch)
- {
- return false;
- }
- }
- }
- if (!m_tag.IsEmpty())
- {
- CComBSTR tagName;
- hr = pEl->get_tagName(&tagName);
- tagName.ToLower();
- if ((hr != S_OK) || (tagName != CComBSTR(m_tag)))
- {
- return false;
- }
- }
-
- // Check attributes
- for (std::vector<CFilterElementHideAttrSelector>::const_iterator attrIt = m_attributeSelectors.begin();
- attrIt != m_attributeSelectors.end(); ++ attrIt)
- {
- ATL::CString value;
- bool attrFound = false;
- if (attrIt->m_type == CFilterElementHideAttrType::STYLE)
- {
- CComPtr<IHTMLStyle> pStyle;
- if (SUCCEEDED(pEl->get_style(&pStyle)) && pStyle)
- {
- CComBSTR bstrStyle;
-
- if (SUCCEEDED(pStyle->get_cssText(&bstrStyle)) && bstrStyle)
- {
- value = bstrStyle;
- value.MakeLower();
- attrFound = true;
- }
- }
- }
- else if (attrIt->m_type == CFilterElementHideAttrType::CLASS)
- {
- CComBSTR bstrClassNames;
- if (SUCCEEDED(pEl->get_className(&bstrClassNames)) && bstrClassNames)
- {
- value = bstrClassNames;
- attrFound = true;
- }
- }
- else if (attrIt->m_type == CFilterElementHideAttrType::ID)
- {
- CComBSTR bstrId;
- if (SUCCEEDED(pEl->get_id(&bstrId)) && bstrId)
- {
- value = bstrId;
- attrFound = true;
- }
- }
- else
- {
- auto attributeValue = GetHtmlElementAttribute(*pEl, attrIt->m_bstrAttr);
- if (attrFound = attributeValue.isAttributeFound)
- {
- value = ToCString(attributeValue.attributeValue);
- }
- }
-
- if (attrFound)
- {
- if (attrIt->m_pos == CFilterElementHideAttrPos::EXACT)
- {
- // TODO: IE rearranges the style attribute completely. Figure out if anything can be done about it.
- if (value != attrIt->m_value)
- return false;
- }
- else if (attrIt->m_pos == CFilterElementHideAttrPos::STARTING)
- {
- if (value.Left(attrIt->m_value.GetLength()) != attrIt->m_value)
- return false;
- }
- else if (attrIt->m_pos == CFilterElementHideAttrPos::ENDING)
- {
- if (value.Right(attrIt->m_value.GetLength()) != attrIt->m_value)
- return false;
- }
- else if (attrIt->m_pos == CFilterElementHideAttrPos::ANYWHERE)
- {
- if (value.Find(attrIt->m_value) < 0)
- return false;
- }
- else if (attrIt->m_value.IsEmpty())
- {
- return true;
- }
- }
- else
- {
- return false;
- }
- }
-
- if (m_predecessor)
- {
- CComPtr<IHTMLElement> pDomPredecessor;
- HRESULT hr = S_FALSE;
- switch (m_predecessor->m_type)
- {
- case ETraverserComplexType::TRAVERSER_TYPE_PARENT:
- hr = pEl->get_parentElement(&pDomPredecessor);
- break;
- case ETraverserComplexType::TRAVERSER_TYPE_IMMEDIATE:
- hr = S_FALSE;
- CComQIPtr<IHTMLDOMNode> pPrevSiblingNode = pEl;
- long type = 0;
- while (pPrevSiblingNode && type != 1)
- {
- IHTMLDOMNode* tmpNode;
- pPrevSiblingNode->get_previousSibling(&tmpNode);
- pPrevSiblingNode.Attach(tmpNode);
- if (pPrevSiblingNode)
- {
- hr = pPrevSiblingNode->get_nodeType(&type);
- if (hr != S_OK)
- pPrevSiblingNode.Release();
- }
- }
-
- if (pPrevSiblingNode)
- hr = pPrevSiblingNode.QueryInterface(&pDomPredecessor);
- else
- return false;
- break;
- }
- if (hr != S_OK)
- return false;
- return m_predecessor->IsMatchFilterElementHide(pDomPredecessor);
- }
-
- return true;
-}
-
-
-
-// ============================================================================
-// CPluginFilter
-// ============================================================================
-
-CPluginFilter::CPluginFilter(const CString& dataPath) : m_dataPath(dataPath)
-{
- m_contentMapText[CFilter::contentTypeDocument] = "DOCUMENT";
- m_contentMapText[CFilter::contentTypeObject] = "OBJECT";
- m_contentMapText[CFilter::contentTypeObjectSubrequest] = "OBJECT_SUBREQUEST";
- m_contentMapText[CFilter::contentTypeImage] = "IMAGE";
- m_contentMapText[CFilter::contentTypeScript] = "SCRIPT";
- m_contentMapText[CFilter::contentTypeOther] = "OTHER";
- m_contentMapText[CFilter::contentTypeUnknown] = "OTHER";
- m_contentMapText[CFilter::contentTypeSubdocument] = "SUBDOCUMENT";
- m_contentMapText[CFilter::contentTypeStyleSheet] = "STYLESHEET";
- m_contentMapText[CFilter::contentTypeXmlHttpRequest] = "XMLHTTPREQUEST";
-
- ClearFilters();
-}
-
-
-bool CPluginFilter::AddFilterElementHide(CString filterText)
-{
- DEBUG_FILTER("Input: " + filterText + " filterFile" + filterFile);
- CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
- {
- CString filterString = filterText;
- // Create filter descriptor
- std::auto_ptr<CFilterElementHide> filter;
-
- CString wholeFilterString = filterString;
- wchar_t separatorChar;
- do
- {
- int chunkEnd = filterText.FindOneOf(L"+>");
- if (chunkEnd > 0)
- {
- separatorChar = filterText.GetAt(chunkEnd);
- }
- else
- {
- chunkEnd = filterText.GetLength();
- separatorChar = L'\0';
- }
-
- CString filterChunk = filterText.Left(chunkEnd).TrimRight();
- std::auto_ptr<CFilterElementHide> filterParent(filter);
-
- filter.reset(new CFilterElementHide(filterChunk));
-
- if (filterParent.get() != 0)
- {
- filter->m_predecessor.reset(filterParent.release());
- }
-
- if (separatorChar != L'\0') // complex selector
- {
- filterText = filterText.Mid(chunkEnd + 1).TrimLeft();
- if (separatorChar == '+')
- filter->m_type = CFilterElementHide::TRAVERSER_TYPE_IMMEDIATE;
- else if (separatorChar == '>')
- filter->m_type = CFilterElementHide::TRAVERSER_TYPE_PARENT;
- }
- else // Terminating element (simple selector)
- {
- if (!filter->m_tagId.IsEmpty())
- {
- m_elementHideTagsId.insert(std::make_pair(std::make_pair(filter->m_tag, filter->m_tagId), *filter));
- }
- else if (!filter->m_tagClassName.IsEmpty())
- {
- m_elementHideTagsClass.insert(std::make_pair(std::make_pair(filter->m_tag, filter->m_tagClassName), *filter));
- }
- else
- {
- std::pair<CString, CFilterElementHide> pair = std::make_pair(filter->m_tag, *filter);
- m_elementHideTags.insert(pair);
- }
- }
- } while (separatorChar != '\0');
- }
-
- return true;
-}
-
-bool CPluginFilter::IsElementHidden(const std::wstring& tag, IHTMLElement* pEl, const std::wstring& domain, const std::wstring& indent) const
-{
- CString tagCString = ToCString(tag);
-
- CString id;
- CComBSTR bstrId;
- if (SUCCEEDED(pEl->get_id(&bstrId)) && bstrId)
- {
- id = bstrId;
- }
-
- CString classNames;
- CComBSTR bstrClassNames;
- if (SUCCEEDED(pEl->get_className(&bstrClassNames)) && bstrClassNames)
- {
- classNames = bstrClassNames;
- }
-
- CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
- {
- // Search tag/id filters
- if (!id.IsEmpty())
- {
- std::pair<TFilterElementHideTagsNamed::const_iterator, TFilterElementHideTagsNamed::const_iterator> idItEnum =
- m_elementHideTagsId.equal_range(std::make_pair(tagCString, id));
- for (TFilterElementHideTagsNamed::const_iterator idIt = idItEnum.first; idIt != idItEnum.second; idIt ++)
- {
- if (idIt->second.IsMatchFilterElementHide(pEl))
- {
-#ifdef ENABLE_DEBUG_RESULT
- DEBUG_HIDE_EL(indent + "HideEl::Found (tag/id) filter:" + idIt->second.m_filterText)
- CPluginDebug::DebugResultHiding(tagCString, L"id:" + id, idIt->second.m_filterText);
-#endif
- return true;
- }
- }
-
- // Search general id
- idItEnum = m_elementHideTagsId.equal_range(std::make_pair("", id));
- for (TFilterElementHideTagsNamed::const_iterator idIt = idItEnum.first; idIt != idItEnum.second; idIt ++)
- {
- if (idIt->second.IsMatchFilterElementHide(pEl))
- {
-#ifdef ENABLE_DEBUG_RESULT
- DEBUG_HIDE_EL(indent + "HideEl::Found (?/id) filter:" + idIt->second.m_filterText)
- CPluginDebug::DebugResultHiding(tagCString, L"id:" + id, idIt->second.m_filterText);
-#endif
- return true;
- }
- }
- }
-
- // Search tag/className filters
- if (!classNames.IsEmpty())
- {
- int pos = 0;
- CString className = classNames.Tokenize(L" \t\n\r", pos);
- while (pos >= 0)
- {
- std::pair<TFilterElementHideTagsNamed::const_iterator, TFilterElementHideTagsNamed::const_iterator> classItEnum =
- m_elementHideTagsClass.equal_range(std::make_pair(tagCString, className));
-
- for (TFilterElementHideTagsNamed::const_iterator classIt = classItEnum.first; classIt != classItEnum.second; ++classIt)
- {
- if (classIt->second.IsMatchFilterElementHide(pEl))
- {
-#ifdef ENABLE_DEBUG_RESULT
- DEBUG_HIDE_EL(indent + "HideEl::Found (tag/class) filter:" + classIt->second.m_filterText)
- CPluginDebug::DebugResultHiding(tagCString, L"class:" + className, classIt->second.m_filterText);
-#endif
- return true;
- }
- }
-
- // Search general class name
- classItEnum = m_elementHideTagsClass.equal_range(std::make_pair("", className));
- for (TFilterElementHideTagsNamed::const_iterator classIt = classItEnum.first; classIt != classItEnum.second; ++ classIt)
- {
- if (classIt->second.IsMatchFilterElementHide(pEl))
- {
-#ifdef ENABLE_DEBUG_RESULT
- DEBUG_HIDE_EL(indent + "HideEl::Found (?/class) filter:" + classIt->second.m_filterText)
- CPluginDebug::DebugResultHiding(tagCString, "class:" + className, classIt->second.m_filterText);
-#endif
- return true;
- }
- }
-
- // Next class name
- className = classNames.Tokenize(L" \t\n\r", pos);
- }
- }
-
- // Search tag filters
- std::pair<TFilterElementHideTags::const_iterator, TFilterElementHideTags::const_iterator> tagItEnum
- = m_elementHideTags.equal_range(tagCString);
- for (TFilterElementHideTags::const_iterator tagIt = tagItEnum.first; tagIt != tagItEnum.second; ++ tagIt)
- {
- if (tagIt->second.IsMatchFilterElementHide(pEl))
- {
-#ifdef ENABLE_DEBUG_RESULT
- DEBUG_HIDE_EL(indent + "HideEl::Found (tag) filter:" + tagIt->second.m_filterText)
- CPluginDebug::DebugResultHiding(tagCString, "-", tagIt->second.m_filterText);
-#endif
- return true;
- }
- }
- }
-
- return false;
-}
-
-bool CPluginFilter::LoadHideFilters(std::vector<std::wstring> filters)
-{
- ClearFilters();
- bool isRead = false;
- CPluginClient* client = CPluginClient::GetInstance();
-
- // Parse hide string
- int pos = 0;
- CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
- {
- for (std::vector<std::wstring>::iterator it = filters.begin(); it < filters.end(); ++it)
- {
- CString filter((*it).c_str());
- // If the line is not commented out
- if (!filter.Trim().IsEmpty() && filter.GetAt(0) != '!' && filter.GetAt(0) != '[')
- {
- int filterType = 0;
-
- // See http://adblockplus.org/en/filters for further documentation
-
- try
- {
- AddFilterElementHide(filter);
- }
- catch(...)
- {
-#ifdef ENABLE_DEBUG_RESULT
- CPluginDebug::DebugResult(L"Error loading hide filter: " + filter);
-#endif
- }
- }
- }
- }
-
- return isRead;
-}
-
-void CPluginFilter::ClearFilters()
-{
- // Clear filter maps
- CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
- {
- for (int i = 0; i < 2; i++)
- {
- for (int j = 0; j < 2; j++)
- {
- m_filterMap[i][j].clear();
- }
- m_filterMapDefault[i].clear();
- }
-
- m_elementHideTags.clear();
- m_elementHideTagsId.clear();
- m_elementHideTagsClass.clear();
- }
-}
-
-bool CPluginFilter::ShouldBlock(const std::wstring& src, int contentType, const std::wstring& domain, bool addDebug) const
-{
- std::wstring srcTrimmed = TrimString(src);
-
- // We should not block the empty string, so all filtering does not make sense
- // Therefore we just return
- if (srcTrimmed.empty())
- {
- return false;
- }
- CPluginSettings* settings = CPluginSettings::GetInstance();
-
- CString type;
- if (addDebug)
- {
- type = "OTHER";
-
- std::map<int,CString>::const_iterator it = m_contentMapText.find(contentType);
- if (it != m_contentMapText.end())
- {
- type = it->second;
- }
- }
-
- CPluginClient* client = CPluginClient::GetInstance();
- if (client->Matches(srcTrimmed, ToWstring(type), domain))
- {
- if (addDebug)
- {
- DEBUG_FILTER("Filter::ShouldBlock " + type + " YES")
-
-#ifdef ENABLE_DEBUG_RESULT
- CPluginDebug::DebugResultBlocking(type, srcTrimmed, domain);
-#endif
- }
- return true;
- }
-#ifdef ENABLE_DEBUG_RESULT
- CPluginDebug::DebugResultIgnoring(type, srcTrimmed, domain);
-#endif
- return false;
-}
+#include "PluginStdAfx.h"
+
+#include "PluginFilter.h"
+#include "PluginSettings.h"
+#include "PluginClient.h"
+#include "PluginClientFactory.h"
+#include "PluginMutex.h"
+#include "PluginSettings.h"
+#include "PluginSystem.h"
+#include "PluginClass.h"
+#include "mlang.h"
+
+#include "..\shared\CriticalSection.h"
+#include "..\shared\Utils.h"
+#include "..\shared\ContentType.h"
+
+
+// The filters are described at http://adblockplus.org/en/filters
+
+static CriticalSection s_criticalSectionFilterMap;
+
+namespace
+{
+ struct GetHtmlElementAttributeResult
+ {
+ GetHtmlElementAttributeResult() : isAttributeFound(false)
+ {
+ }
+ std::wstring attributeValue;
+ bool isAttributeFound;
+ };
+
+ GetHtmlElementAttributeResult GetHtmlElementAttribute(IHTMLElement& htmlElement,
+ const ATL::CComBSTR& attributeName)
+ {
+ GetHtmlElementAttributeResult retValue;
+ ATL::CComVariant vAttr;
+ ATL::CComPtr<IHTMLElement4> htmlElement4;
+ if (FAILED(htmlElement.QueryInterface(&htmlElement4)) || !htmlElement4)
+ {
+ return retValue;
+ }
+ ATL::CComPtr<IHTMLDOMAttribute> attributeNode;
+ if (FAILED(htmlElement4->getAttributeNode(attributeName, &attributeNode)) || !attributeNode)
+ {
+ return retValue;
+ }
+ // we set that attribute found but it's not necessary that we can retrieve its value
+ retValue.isAttributeFound = true;
+ if (FAILED(attributeNode->get_nodeValue(&vAttr)))
+ {
+ return retValue;
+ }
+ if (vAttr.vt == VT_BSTR && vAttr.bstrVal)
+ {
+ retValue.attributeValue = vAttr.bstrVal;
+ }
+ else if (vAttr.vt == VT_I4)
+ {
+ retValue.attributeValue = std::to_wstring(vAttr.iVal);
+ }
+ return retValue;
+ }
+}
+
+// ============================================================================
+// CFilterElementHideAttrSelector
+// ============================================================================
+
+CFilterElementHideAttrSelector::CFilterElementHideAttrSelector() : m_type(TYPE_NONE), m_pos(POS_NONE), m_bstrAttr(NULL)
+{
+}
+
+CFilterElementHideAttrSelector::CFilterElementHideAttrSelector(const CFilterElementHideAttrSelector& filter)
+{
+ m_type = filter.m_type;
+ m_pos = filter.m_pos;
+ m_bstrAttr = filter.m_bstrAttr;
+
+ m_value = filter.m_value;
+}
+
+CFilterElementHideAttrSelector::~CFilterElementHideAttrSelector()
+{
+}
+
+
+// ============================================================================
+// CFilterElementHide
+// ============================================================================
+
+CFilterElementHide::CFilterElementHide(const CString& filterText) : m_filterText(filterText), m_type(ETraverserComplexType::TRAVERSER_TYPE_ERROR)
+{
+ // Find tag name, class or any (*)
+ CString filterString = filterText;
+
+ wchar_t firstTag = filterString.GetAt(0);
+ // Any tag
+ if (firstTag == '*')
+ {
+ filterString = filterString.Mid(1);
+ }
+ // Any tag (implicitely)
+ else if (firstTag == '[' || firstTag == '.' || firstTag == '#')
+ {
+ }
+ // Real tag
+ else if (isalnum(firstTag))
+ {
+ //TODO: Add support for descendant selectors
+ int pos = filterString.FindOneOf(L".#[(");
+
+ if (pos < 0)
+ pos = filterString.GetLength();
+ m_tag = filterString.Left(pos).MakeLower();
+
+ filterString = filterString.Mid(pos);
+ }
+ // Error
+ else
+ {
+ DEBUG_FILTER("Filter::Error parsing selector:" + filterText + " (invalid tag)");
+ throw std::runtime_error(CStringA("Filter::Error parsing selector:" + filterText + " (invalid tag)").GetString());
+ }
+
+ // Find Id and class name
+
+ if (!filterString.IsEmpty())
+ {
+ wchar_t firstId = filterString.GetAt(0);
+
+ // Id
+ if (firstId == '#')
+ {
+ int pos = filterString.Find('[');
+ if (pos < 0)
+ {
+ pos = filterString.GetLength();
+ }
+ m_tagId = filterString.Mid(1, pos - 1);
+ filterString = filterString.Mid(pos);
+ pos = m_tagId.Find(L".");
+ if (pos > 0)
+ {
+ m_tagClassName = m_tagId.Mid(pos + 1);
+ m_tagId = m_tagId.Left(pos);
+ }
+ }
+ // Class name
+ else if (firstId == '.')
+ {
+ int pos = filterString.Find('[');
+ if (pos < 0)
+ {
+ pos = filterString.GetLength();
+ }
+ m_tagClassName = filterString.Mid(1, pos - 1);
+ filterString = filterString.Mid(pos);
+ }
+ }
+
+ char chAttrStart = '[';
+ char chAttrEnd = ']';
+
+ while (!filterString.IsEmpty())
+ {
+ if (filterString.GetAt(0) != chAttrStart)
+ {
+ DEBUG_FILTER("Filter::Error parsing selector:" + filterText + " (more data)");
+ throw std::runtime_error(CStringA("Filter::Error parsing selector:" + filterText + " (more data)").GetString());
+ }
+ int endPos = filterString.Find(']') ;
+ if (endPos < 0)
+ {
+ DEBUG_FILTER("Filter::Error parsing selector:" + filterText + " (more data)");
+ throw std::runtime_error(CStringA("Filter::Error parsing selector:" + filterText + " (more data)").GetString());
+ }
+
+ CFilterElementHideAttrSelector attrSelector;
+
+ CString arg = filterString.Mid(1, endPos - 1);
+ filterString = filterString.Mid(endPos + 1);
+
+ int delimiterPos = arg.Find('=');
+ if (delimiterPos > 0)
+ {
+ attrSelector.m_value = arg.Mid(delimiterPos + 1);
+ if (attrSelector.m_value.GetLength() >= 2 && attrSelector.m_value.GetAt(0) == '\"' && attrSelector.m_value.GetAt(attrSelector.m_value.GetLength() - 1) == '\"')
+ {
+ attrSelector.m_value = attrSelector.m_value.Mid(1, attrSelector.m_value.GetLength() - 2);
+ }
+
+ if (arg.GetAt(delimiterPos - 1) == '^')
+ {
+ attrSelector.m_bstrAttr = arg.Left(delimiterPos - 1);
+ attrSelector.m_pos = CFilterElementHideAttrPos::STARTING;
+ }
+ else if (arg.GetAt(delimiterPos - 1) == '*')
+ {
+ attrSelector.m_bstrAttr = arg.Left(delimiterPos - 1);
+ attrSelector.m_pos = CFilterElementHideAttrPos::ANYWHERE;
+ }
+ else if (arg.GetAt(delimiterPos - 1) == '$')
+ {
+ attrSelector.m_bstrAttr = arg.Left(delimiterPos - 1);
+ attrSelector.m_pos = CFilterElementHideAttrPos::ENDING;
+ }
+ else
+ {
+ attrSelector.m_bstrAttr = arg.Left(delimiterPos);
+ attrSelector.m_pos = CFilterElementHideAttrPos::EXACT;
+ }
+ }
+ CString tag = attrSelector.m_bstrAttr;
+ if (tag == "style")
+ {
+ attrSelector.m_type = CFilterElementHideAttrType::STYLE;
+ attrSelector.m_value.MakeLower();
+ }
+ else if (tag == "id")
+ {
+ attrSelector.m_type = CFilterElementHideAttrType::ID;
+ }
+ else if (tag == "class")
+ {
+ attrSelector.m_type = CFilterElementHideAttrType::CLASS;
+ }
+ m_attributeSelectors.push_back(attrSelector);
+
+ }
+
+ // End check
+ if (!filterString.IsEmpty())
+ {
+ DEBUG_FILTER("Filter::Error parsing selector:" + filterFile + "/" + filterText + " (more data)")
+ throw new std::runtime_error(CStringA("Filter::Error parsing selector:" + filterText + " (more data)").GetString());
+ }
+}
+
+CFilterElementHide::CFilterElementHide(const CFilterElementHide& filter)
+{
+ m_filterText = filter.m_filterText;
+
+ m_tagId = filter.m_tagId;
+ m_tagClassName = filter.m_tagClassName;
+
+ m_attributeSelectors = filter.m_attributeSelectors;
+
+ m_predecessor = filter.m_predecessor;
+}
+
+
+// ============================================================================
+// CFilter
+// ============================================================================
+
+CFilter::CFilter(const CFilter& filter)
+{
+ m_contentType = filter.m_contentType;
+ m_filterType = filter.m_filterType;
+
+ m_isFirstParty = filter.m_isFirstParty;
+ m_isThirdParty = filter.m_isThirdParty;
+
+ m_isMatchCase = filter.m_isMatchCase;
+ m_isFromStart = filter.m_isFromStart;
+ m_isFromEnd = filter.m_isFromEnd;
+
+ m_filterText = filter.m_filterText;
+
+ m_hitCount = filter.m_hitCount;
+}
+
+
+CFilter::CFilter() : m_isMatchCase(false), m_isFirstParty(false),
+ m_isThirdParty(false), m_contentType(AdblockPlus::FilterEngine::ContentType::CONTENT_TYPE_OTHER),
+ m_isFromStart(false), m_isFromEnd(false), m_hitCount(0)
+{
+}
+
+
+bool CFilterElementHide::IsMatchFilterElementHide(IHTMLElement* pEl) const
+{
+ HRESULT hr;
+
+ if (!m_tagId.IsEmpty())
+ {
+ CComBSTR id;
+ hr = pEl->get_id(&id);
+ if ((hr != S_OK) || (id != CComBSTR(m_tagId)))
+ {
+ return false;
+ }
+ }
+ if (!m_tagClassName.IsEmpty())
+ {
+ CComBSTR classNameBSTR;
+ hr = pEl->get_className(&classNameBSTR);
+ if (hr == S_OK)
+ {
+ CString className = classNameBSTR;
+ int start = 0;
+ CString specificClass;
+ bool foundMatch = false;
+ while ((specificClass = className.Tokenize(L" ", start)) != L"")
+ {
+ // TODO: Consider case of multiple classes. (m_tagClassName can be something like "foo.bar")
+ if (specificClass == m_tagClassName)
+ {
+ foundMatch = true;
+ }
+ }
+ if (!foundMatch)
+ {
+ return false;
+ }
+ }
+ }
+ if (!m_tag.IsEmpty())
+ {
+ CComBSTR tagName;
+ hr = pEl->get_tagName(&tagName);
+ tagName.ToLower();
+ if ((hr != S_OK) || (tagName != CComBSTR(m_tag)))
+ {
+ return false;
+ }
+ }
+
+ // Check attributes
+ for (std::vector<CFilterElementHideAttrSelector>::const_iterator attrIt = m_attributeSelectors.begin();
+ attrIt != m_attributeSelectors.end(); ++ attrIt)
+ {
+ ATL::CString value;
+ bool attrFound = false;
+ if (attrIt->m_type == CFilterElementHideAttrType::STYLE)
+ {
+ CComPtr<IHTMLStyle> pStyle;
+ if (SUCCEEDED(pEl->get_style(&pStyle)) && pStyle)
+ {
+ CComBSTR bstrStyle;
+
+ if (SUCCEEDED(pStyle->get_cssText(&bstrStyle)) && bstrStyle)
+ {
+ value = bstrStyle;
+ value.MakeLower();
+ attrFound = true;
+ }
+ }
+ }
+ else if (attrIt->m_type == CFilterElementHideAttrType::CLASS)
+ {
+ CComBSTR bstrClassNames;
+ if (SUCCEEDED(pEl->get_className(&bstrClassNames)) && bstrClassNames)
+ {
+ value = bstrClassNames;
+ attrFound = true;
+ }
+ }
+ else if (attrIt->m_type == CFilterElementHideAttrType::ID)
+ {
+ CComBSTR bstrId;
+ if (SUCCEEDED(pEl->get_id(&bstrId)) && bstrId)
+ {
+ value = bstrId;
+ attrFound = true;
+ }
+ }
+ else
+ {
+ auto attributeValue = GetHtmlElementAttribute(*pEl, attrIt->m_bstrAttr);
+ if (attrFound = attributeValue.isAttributeFound)
+ {
+ value = ToCString(attributeValue.attributeValue);
+ }
+ }
+
+ if (attrFound)
+ {
+ if (attrIt->m_pos == CFilterElementHideAttrPos::EXACT)
+ {
+ // TODO: IE rearranges the style attribute completely. Figure out if anything can be done about it.
+ if (value != attrIt->m_value)
+ return false;
+ }
+ else if (attrIt->m_pos == CFilterElementHideAttrPos::STARTING)
+ {
+ if (value.Left(attrIt->m_value.GetLength()) != attrIt->m_value)
+ return false;
+ }
+ else if (attrIt->m_pos == CFilterElementHideAttrPos::ENDING)
+ {
+ if (value.Right(attrIt->m_value.GetLength()) != attrIt->m_value)
+ return false;
+ }
+ else if (attrIt->m_pos == CFilterElementHideAttrPos::ANYWHERE)
+ {
+ if (value.Find(attrIt->m_value) < 0)
+ return false;
+ }
+ else if (attrIt->m_value.IsEmpty())
+ {
+ return true;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ if (m_predecessor)
+ {
+ CComPtr<IHTMLElement> pDomPredecessor;
+ HRESULT hr = S_FALSE;
+ switch (m_predecessor->m_type)
+ {
+ case ETraverserComplexType::TRAVERSER_TYPE_PARENT:
+ hr = pEl->get_parentElement(&pDomPredecessor);
+ break;
+ case ETraverserComplexType::TRAVERSER_TYPE_IMMEDIATE:
+ hr = S_FALSE;
+ CComQIPtr<IHTMLDOMNode> pPrevSiblingNode = pEl;
+ long type = 0;
+ while (pPrevSiblingNode && type != 1)
+ {
+ IHTMLDOMNode* tmpNode;
+ pPrevSiblingNode->get_previousSibling(&tmpNode);
+ pPrevSiblingNode.Attach(tmpNode);
+ if (pPrevSiblingNode)
+ {
+ hr = pPrevSiblingNode->get_nodeType(&type);
+ if (hr != S_OK)
+ pPrevSiblingNode.Release();
+ }
+ }
+
+ if (pPrevSiblingNode)
+ hr = pPrevSiblingNode.QueryInterface(&pDomPredecessor);
+ else
+ return false;
+ break;
+ }
+ if (hr != S_OK)
+ return false;
+ return m_predecessor->IsMatchFilterElementHide(pDomPredecessor);
+ }
+
+ return true;
+}
+
+
+
+// ============================================================================
+// CPluginFilter
+// ============================================================================
+
+CPluginFilter::CPluginFilter(const CString& dataPath) : m_dataPath(dataPath)
+{
+ ClearFilters();
+}
+
+
+bool CPluginFilter::AddFilterElementHide(CString filterText)
+{
+ DEBUG_FILTER("Input: " + filterText + " filterFile" + filterFile);
+ CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
+ {
+ CString filterString = filterText;
+ // Create filter descriptor
+ std::auto_ptr<CFilterElementHide> filter;
+
+ CString wholeFilterString = filterString;
+ wchar_t separatorChar;
+ do
+ {
+ int chunkEnd = filterText.FindOneOf(L"+>");
+ if (chunkEnd > 0)
+ {
+ separatorChar = filterText.GetAt(chunkEnd);
+ }
+ else
+ {
+ chunkEnd = filterText.GetLength();
+ separatorChar = L'\0';
+ }
+
+ CString filterChunk = filterText.Left(chunkEnd).TrimRight();
+ std::auto_ptr<CFilterElementHide> filterParent(filter);
+
+ filter.reset(new CFilterElementHide(filterChunk));
+
+ if (filterParent.get() != 0)
+ {
+ filter->m_predecessor.reset(filterParent.release());
+ }
+
+ if (separatorChar != L'\0') // complex selector
+ {
+ filterText = filterText.Mid(chunkEnd + 1).TrimLeft();
+ if (separatorChar == '+')
+ filter->m_type = CFilterElementHide::TRAVERSER_TYPE_IMMEDIATE;
+ else if (separatorChar == '>')
+ filter->m_type = CFilterElementHide::TRAVERSER_TYPE_PARENT;
+ }
+ else // Terminating element (simple selector)
+ {
+ if (!filter->m_tagId.IsEmpty())
+ {
+ m_elementHideTagsId.insert(std::make_pair(std::make_pair(filter->m_tag, filter->m_tagId), *filter));
+ }
+ else if (!filter->m_tagClassName.IsEmpty())
+ {
+ m_elementHideTagsClass.insert(std::make_pair(std::make_pair(filter->m_tag, filter->m_tagClassName), *filter));
+ }
+ else
+ {
+ std::pair<CString, CFilterElementHide> pair = std::make_pair(filter->m_tag, *filter);
+ m_elementHideTags.insert(pair);
+ }
+ }
+ } while (separatorChar != '\0');
+ }
+
+ return true;
+}
+
+bool CPluginFilter::IsElementHidden(const std::wstring& tag, IHTMLElement* pEl, const std::wstring& domain, const std::wstring& indent) const
+{
+ CString tagCString = ToCString(tag);
+
+ CString id;
+ CComBSTR bstrId;
+ if (SUCCEEDED(pEl->get_id(&bstrId)) && bstrId)
+ {
+ id = bstrId;
+ }
+
+ CString classNames;
+ CComBSTR bstrClassNames;
+ if (SUCCEEDED(pEl->get_className(&bstrClassNames)) && bstrClassNames)
+ {
+ classNames = bstrClassNames;
+ }
+
+ CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
+ {
+ // Search tag/id filters
+ if (!id.IsEmpty())
+ {
+ std::pair<TFilterElementHideTagsNamed::const_iterator, TFilterElementHideTagsNamed::const_iterator> idItEnum =
+ m_elementHideTagsId.equal_range(std::make_pair(tagCString, id));
+ for (TFilterElementHideTagsNamed::const_iterator idIt = idItEnum.first; idIt != idItEnum.second; idIt ++)
+ {
+ if (idIt->second.IsMatchFilterElementHide(pEl))
+ {
+#ifdef ENABLE_DEBUG_RESULT
+ DEBUG_HIDE_EL(indent + "HideEl::Found (tag/id) filter:" + idIt->second.m_filterText)
+ CPluginDebug::DebugResultHiding(tagCString, L"id:" + id, idIt->second.m_filterText);
+#endif
+ return true;
+ }
+ }
+
+ // Search general id
+ idItEnum = m_elementHideTagsId.equal_range(std::make_pair("", id));
+ for (TFilterElementHideTagsNamed::const_iterator idIt = idItEnum.first; idIt != idItEnum.second; idIt ++)
+ {
+ if (idIt->second.IsMatchFilterElementHide(pEl))
+ {
+#ifdef ENABLE_DEBUG_RESULT
+ DEBUG_HIDE_EL(indent + "HideEl::Found (?/id) filter:" + idIt->second.m_filterText)
+ CPluginDebug::DebugResultHiding(tagCString, L"id:" + id, idIt->second.m_filterText);
+#endif
+ return true;
+ }
+ }
+ }
+
+ // Search tag/className filters
+ if (!classNames.IsEmpty())
+ {
+ int pos = 0;
+ CString className = classNames.Tokenize(L" \t\n\r", pos);
+ while (pos >= 0)
+ {
+ std::pair<TFilterElementHideTagsNamed::const_iterator, TFilterElementHideTagsNamed::const_iterator> classItEnum =
+ m_elementHideTagsClass.equal_range(std::make_pair(tagCString, className));
+
+ for (TFilterElementHideTagsNamed::const_iterator classIt = classItEnum.first; classIt != classItEnum.second; ++classIt)
+ {
+ if (classIt->second.IsMatchFilterElementHide(pEl))
+ {
+#ifdef ENABLE_DEBUG_RESULT
+ DEBUG_HIDE_EL(indent + "HideEl::Found (tag/class) filter:" + classIt->second.m_filterText)
+ CPluginDebug::DebugResultHiding(tagCString, L"class:" + className, classIt->second.m_filterText);
+#endif
+ return true;
+ }
+ }
+
+ // Search general class name
+ classItEnum = m_elementHideTagsClass.equal_range(std::make_pair("", className));
+ for (TFilterElementHideTagsNamed::const_iterator classIt = classItEnum.first; classIt != classItEnum.second; ++ classIt)
+ {
+ if (classIt->second.IsMatchFilterElementHide(pEl))
+ {
+#ifdef ENABLE_DEBUG_RESULT
+ DEBUG_HIDE_EL(indent + "HideEl::Found (?/class) filter:" + classIt->second.m_filterText)
+ CPluginDebug::DebugResultHiding(tagCString, "class:" + className, classIt->second.m_filterText);
+#endif
+ return true;
+ }
+ }
+
+ // Next class name
+ className = classNames.Tokenize(L" \t\n\r", pos);
+ }
+ }
+
+ // Search tag filters
+ std::pair<TFilterElementHideTags::const_iterator, TFilterElementHideTags::const_iterator> tagItEnum
+ = m_elementHideTags.equal_range(tagCString);
+ for (TFilterElementHideTags::const_iterator tagIt = tagItEnum.first; tagIt != tagItEnum.second; ++ tagIt)
+ {
+ if (tagIt->second.IsMatchFilterElementHide(pEl))
+ {
+#ifdef ENABLE_DEBUG_RESULT
+ DEBUG_HIDE_EL(indent + "HideEl::Found (tag) filter:" + tagIt->second.m_filterText)
+ CPluginDebug::DebugResultHiding(tagCString, "-", tagIt->second.m_filterText);
+#endif
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool CPluginFilter::LoadHideFilters(std::vector<std::wstring> filters)
+{
+ ClearFilters();
+ bool isRead = false;
+ CPluginClient* client = CPluginClient::GetInstance();
+
+ // Parse hide string
+ int pos = 0;
+ CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
+ {
+ for (std::vector<std::wstring>::iterator it = filters.begin(); it < filters.end(); ++it)
+ {
+ CString filter((*it).c_str());
+ // If the line is not commented out
+ if (!filter.Trim().IsEmpty() && filter.GetAt(0) != '!' && filter.GetAt(0) != '[')
+ {
+ int filterType = 0;
+
+ // See http://adblockplus.org/en/filters for further documentation
+
+ try
+ {
+ AddFilterElementHide(filter);
+ }
+ catch(...)
+ {
+#ifdef ENABLE_DEBUG_RESULT
+ CPluginDebug::DebugResult(L"Error loading hide filter: " + filter);
+#endif
+ }
+ }
+ }
+ }
+
+ return isRead;
+}
+
+void CPluginFilter::ClearFilters()
+{
+ // Clear filter maps
+ CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
+ {
+ for (int i = 0; i < 2; i++)
+ {
+ for (int j = 0; j < 2; j++)
+ {
+ m_filterMap[i][j].clear();
+ }
+ m_filterMapDefault[i].clear();
+ }
+
+ m_elementHideTags.clear();
+ m_elementHideTagsId.clear();
+ m_elementHideTagsClass.clear();
+ }
+}
+
+bool CPluginFilter::ShouldBlock(const std::wstring& src, AdblockPlus::FilterEngine::ContentType contentType, const std::wstring& domain, bool addDebug) const
+{
+ std::wstring srcTrimmed = TrimString(src);
+
+ // We should not block the empty string, so all filtering does not make sense
+ // Therefore we just return
+ if (srcTrimmed.empty())
+ {
+ return false;
+ }
+
+ CPluginSettings* settings = CPluginSettings::GetInstance();
+
+ CPluginClient* client = CPluginClient::GetInstance();
+ bool result = client->Matches(srcTrimmed, contentType, domain);
+
+#ifdef ENABLE_DEBUG_RESULT
+ if (addDebug)
+ {
+ std::wstring type = ToUtf16String(AdblockPlus::FilterEngine::ContentTypeToString(contentType));
+ if (result)
+ {
+ CPluginDebug::DebugResultBlocking(ToCString(type), srcTrimmed, domain);
+ }
+ else
+ {
+ CPluginDebug::DebugResultIgnoring(ToCString(type), srcTrimmed, domain);
+ }
+ }
+#endif
+ return result;
+}

Powered by Google App Engine
This is Rietveld