Index: src/plugin/PluginFilter.cpp
===================================================================
--- a/src/plugin/PluginFilter.cpp
+++ b/src/plugin/PluginFilter.cpp
@@ -11,12 +11,89 @@
#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
+{
+ // Returns attribute value and the bool flag which indicates whether the attribute is found.
+ // For the cases like IE returns the value of 'on-some-event'
+ // attribute as 'function(event){\ndo();\n}'. Our filters are not designed for such
+ // transformations, so this method retrives the value of (body) of /^.*?\{(body)\}$/ as well.
+ std::pair GetHtmlElementAttribute(IHTMLElement& htmlElement, const ATL::CComBSTR& attributeName)
+ {
+ std::pair retResult;
+ retResult.second = false;
+ ATL::CComVariant vAttr;
+ // Performs a property search that is not case-sensitive,
+ // and returns an interpolated value if the property is found.
+ LONG flags = 0;
+ if (FAILED(htmlElement.getAttribute(attributeName, flags, &vAttr)))
+ {
+ return retResult;
+ }
+ // we set that attribute found but it's not necessary that we can retrieve its value
+ retResult.second = true;
+ if (vAttr.vt == VT_BSTR && vAttr.bstrVal)
+ {
+ retResult.first.assign(vAttr.bstrVal);
+ }
+ else if (vAttr.vt == VT_I4)
+ {
+ retResult.first = std::to_wstring(vAttr.iVal);
+ }
+ else if (vAttr.vt == VT_DISPATCH)
+ {
+ wchar_t* toStringMethod = L"toString";
+ DISPID methodId = 0;
+ if (FAILED(vAttr.pdispVal->GetIDsOfNames(/*must be null iid*/IID_NULL, &toStringMethod,
+ /*cNames*/1, LOCALE_SYSTEM_DEFAULT, &methodId)))
+ {
+ return retResult;
+ }
+ ATL::CComVariant variantFunctionAsString; // result of IDispatch::Invoke
+ DISPID dispidNamed = DISPATCH_METHOD | DISPATCH_PROPERTYGET;
+ DISPPARAMS dispparams;
+ dispparams.rgvarg = &variantFunctionAsString;
+ dispparams.cArgs = 1;
+ dispparams.cNamedArgs = 1;
+ dispparams.rgdispidNamedArgs = &dispidNamed;
+ UINT ArgErr = 0;
+ if (FAILED(vAttr.pdispVal->Invoke(methodId, /*must be null iid*/IID_NULL,
+ LOCALE_SYSTEM_DEFAULT, dispidNamed, &dispparams, &variantFunctionAsString, /*exception info*/nullptr,
+ &ArgErr)))
+ {
+ return retResult;
+ }
+ if (variantFunctionAsString.vt != VT_BSTR)
+ {
+ return retResult;
+ }
+ std::wstring functionAsString = variantFunctionAsString.bstrVal;
+ auto bodyBeginsAt = functionAsString.find(L'{');
+ if (bodyBeginsAt == std::wstring::npos)
+ {
+ return retResult;
+ }
+ // eat spaces
+ while (::iswspace(functionAsString[++bodyBeginsAt]));
+ auto bodyEndsAt = functionAsString.rfind(L'}');
+ if (bodyEndsAt == std::wstring::npos || bodyEndsAt < bodyBeginsAt)
+ {
+ return retResult;
+ }
+ // eat spaces
+ while(::iswspace(functionAsString[--bodyEndsAt]));
+ retResult.first = functionAsString.substr(bodyBeginsAt, bodyEndsAt - bodyBeginsAt + 1);
+ }
+ return retResult;
+ }
+}
+
// ============================================================================
// CFilterElementHideAttrSelector
// ============================================================================
@@ -272,8 +349,8 @@
if (!m_tag.IsEmpty())
{
CComBSTR tagName;
+ hr = pEl->get_tagName(&tagName);
tagName.ToLower();
- hr = pEl->get_tagName(&tagName);
if ((hr != S_OK) || (tagName != CComBSTR(m_tag)))
{
return false;
@@ -284,7 +361,7 @@
for (std::vector::const_iterator attrIt = m_attributeSelectors.begin();
attrIt != m_attributeSelectors.end(); ++ attrIt)
{
- CString value;
+ ATL::CString value;
bool attrFound = false;
if (attrIt->m_type == CFilterElementHideAttrType::STYLE)
{
@@ -319,20 +396,12 @@
attrFound = true;
}
}
- else
+ else
{
- CComVariant vAttr;
- if (SUCCEEDED(pEl->getAttribute(attrIt->m_bstrAttr, 0, &vAttr)))
+ auto attribute = GetHtmlElementAttribute(*pEl, attrIt->m_bstrAttr);
+ if (attrFound = attribute.second)
{
- attrFound = true;
- if (vAttr.vt == VT_BSTR)
- {
- value = vAttr.bstrVal;
- }
- else if (vAttr.vt == VT_I4)
- {
- value.Format(L"%u", vAttr.iVal);
- }
+ value = ToCString(attribute.first);
}
}
@@ -435,13 +504,9 @@
bool CPluginFilter::AddFilterElementHide(CString filterText)
{
-
-
DEBUG_FILTER("Input: " + filterText + " filterFile" + filterFile);
-
- CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
+ CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
{
-
CString filterString = filterText;
// Create filter descriptor
std::auto_ptr filter;
@@ -464,7 +529,7 @@
CString filterChunk = filterText.Left(chunkEnd).TrimRight();
std::auto_ptr filterParent(filter);
- filter.reset(new CFilterElementHide(filterChunk));
+ filter.reset(new CFilterElementHide(filterChunk));
if (filterParent.get() != 0)
{
@@ -519,7 +584,7 @@
classNames = bstrClassNames;
}
- CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
+ CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
{
// Search tag/id filters
if (!id.IsEmpty())
@@ -621,7 +686,7 @@
// Parse hide string
int pos = 0;
- CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
+ CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
{
for (std::vector::iterator it = filters.begin(); it < filters.end(); ++it)
{