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 <some-tag on-some-event="do();"/> 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<std::wstring, bool> GetHtmlElementAttribute(IHTMLElement& htmlElement, const ATL::CComBSTR& attributeName) |
+ { |
+ std::pair<std::wstring, bool> 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<CFilterElementHideAttrSelector>::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<CFilterElementHide> filter; |
@@ -464,7 +529,7 @@ |
CString filterChunk = filterText.Left(chunkEnd).TrimRight(); |
std::auto_ptr<CFilterElementHide> 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<std::wstring>::iterator it = filters.begin(); it < filters.end(); ++it) |
{ |