void CopyToParamList(const list<wstring>& inList, ISC_StrParamList* paramList) { INIT_FUNCTION_SCOPE_LOGGER(); try { paramList->len = inList.size(); paramList->dataItems = new ISC_STRING[paramList->len]; int i = 0; for (auto str : inList) { paramList->dataItems[i] = ToDoubleByte(str); LOGD("Setting parameter " << Utils::ToWide(paramList->dataItems[i], str.length())); i++; } } catch (exception ex) { LOGD(L"Exception - " << ToWstring(ex.what())); } catch (...) { LOGD(L"Unknown exception"); } }
void CopyToParamList(const vector<long>& inList, ISC_LongParamList* const paramList) { INIT_FUNCTION_SCOPE_LOGGER(); try { paramList->len = inList.size(); paramList->dataItems = new long[paramList->len]; int i = 0; for (auto num : inList) { paramList->dataItems[i] |= num; i++; } } catch (exception ex) { LOGD(L"Exception - " << ToWstring(ex.what())); } catch (...) { LOGD(L"Unknown exception"); } }
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: " + ToWstring(filter)); #endif } } } } return isRead; }
STDMETHODIMP CPluginUserSettings::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispparams, VARIANT* pVarResult, EXCEPINFO* pExcepinfo, UINT* pArgErr) { try { if (!pDispparams) { return E_POINTER; } if (pDispparams->cNamedArgs != 0) { return DISP_E_NONAMEDARGS; } CPluginSettings* settings = CPluginSettings::GetInstance(); switch (dispidMember) { case dispatchID_GetMessage: { if (pDispparams->cArgs != 2) { return DISP_E_BADPARAMCOUNT; } if (pDispparams->rgvarg[0].vt != VT_BSTR || pDispparams->rgvarg[1].vt != VT_BSTR) { return DISP_E_TYPEMISMATCH; } if (pVarResult) { CComBSTR key = pDispparams->rgvarg[0].bstrVal; CComBSTR section = pDispparams->rgvarg[1].bstrVal; Dictionary* dictionary = Dictionary::GetInstance(); std::wstring message = dictionary->Lookup( ToUtf8String(ToWstring(section)), ToUtf8String(ToWstring(key)) ); pVarResult->vt = VT_BSTR; pVarResult->bstrVal = SysAllocString(message.c_str()); } } break; case dispatchID_GetLanguageCount: { if (pDispparams->cArgs != 0) { return DISP_E_BADPARAMCOUNT; } if (pVarResult) { auto languageList = settings->GetFilterLanguageTitleList(); pVarResult->vt = VT_I4; pVarResult->lVal = static_cast<LONG>(languageList.size()); } } break; case dispatchID_GetLanguageByIndex: { if (pDispparams->cArgs != 1) { return DISP_E_BADPARAMCOUNT; } if (pDispparams->rgvarg[0].vt != VT_I4) { return DISP_E_TYPEMISMATCH; } if (pVarResult) { int index = pDispparams->rgvarg[0].lVal; auto languageTitleList = settings->GetFilterLanguageTitleList(); if (index < 0 || index >= static_cast<int>(languageTitleList.size())) return DISP_E_BADINDEX; std::wstring language; int loopIndex = 0; for (auto it = languageTitleList.begin(); it != languageTitleList.end(); ++it) { if (loopIndex == index) { language = it->first; break; } ++loopIndex; } pVarResult->vt = VT_BSTR; pVarResult->bstrVal = SysAllocString(language.c_str()); } } break; case dispatchID_GetLanguageTitleByIndex: { if (pDispparams->cArgs != 1) { return DISP_E_BADPARAMCOUNT; } if (pDispparams->rgvarg[0].vt != VT_I4) { return DISP_E_TYPEMISMATCH; } if (pVarResult) { int index = pDispparams->rgvarg[0].lVal; auto languageTitleList = settings->GetFilterLanguageTitleList(); if (index < 0 || index >= static_cast<int>(languageTitleList.size())) return DISP_E_BADINDEX; std::wstring languageTitle; int loopIndex = 0; for (auto it = languageTitleList.begin(); it != languageTitleList.end(); ++it) { if (loopIndex == index) { languageTitle = it->second; break; } loopIndex++; } pVarResult->vt = VT_BSTR; pVarResult->bstrVal = SysAllocString(languageTitle.c_str()); } } break; case dispatchID_SetLanguage: { if (pDispparams->cArgs != 1) { return DISP_E_BADPARAMCOUNT; } if (pDispparams->rgvarg[0].vt != VT_BSTR) { return DISP_E_TYPEMISMATCH; } CComBSTR url = pDispparams->rgvarg[0].bstrVal; settings->SetSubscription((BSTR)url); } break; case dispatchID_GetLanguage: { if (pDispparams->cArgs != 0) { return DISP_E_BADPARAMCOUNT; } if (pVarResult) { std::wstring url = settings->GetSubscription(); pVarResult->vt = VT_BSTR; pVarResult->bstrVal = SysAllocString(url.c_str()); } } break; case dispatchID_GetWhitelistDomains: { if (pDispparams->cArgs != 0) { return DISP_E_BADPARAMCOUNT; } if (pVarResult) { auto whiteListDomains = settings->GetWhiteListedDomainList(); std::wstring commaSeparatedDomains; for (size_t i = 0; i < whiteListDomains.size(); i++) { if (!commaSeparatedDomains.empty()) { commaSeparatedDomains += ','; } commaSeparatedDomains += whiteListDomains[i]; } pVarResult->vt = VT_BSTR; pVarResult->bstrVal = SysAllocString(commaSeparatedDomains.c_str()); } } break; case dispatchID_AddWhitelistDomain: { if (pDispparams->cArgs != 1) { return DISP_E_BADPARAMCOUNT; } if (pDispparams->rgvarg[0].vt != VT_BSTR) { return DISP_E_TYPEMISMATCH; } CComBSTR domain = pDispparams->rgvarg[0].bstrVal; if (domain.Length()) { settings->AddWhiteListedDomain((BSTR)domain); } } break; case dispatchID_RemoveWhitelistDomain: { if (pDispparams->cArgs != 1) { return DISP_E_BADPARAMCOUNT; } if (pDispparams->rgvarg[0].vt != VT_BSTR) { return DISP_E_TYPEMISMATCH; } CComBSTR domain = pDispparams->rgvarg[0].bstrVal; if (domain.Length()) { settings->RemoveWhiteListedDomain(std::wstring(domain)); } } break; case dispatchID_GetAppLocale: { if (pDispparams->cArgs != 0) { return DISP_E_BADPARAMCOUNT; } if (pVarResult) { pVarResult->vt = VT_BSTR; pVarResult->bstrVal = SysAllocString(GetBrowserLanguage().c_str()); } } break; case dispatchID_GetDocumentationLink: { if (pDispparams->cArgs != 0) { return DISP_E_BADPARAMCOUNT; } if (pVarResult) { pVarResult->vt = VT_BSTR; pVarResult->bstrVal = SysAllocString(CPluginClient::GetInstance()->GetDocumentationLink().c_str()); } } break; case dispatchID_IsAcceptableAdsEnabled: { if (pDispparams->cArgs != 0) { return DISP_E_BADPARAMCOUNT; } if (pVarResult) { pVarResult->vt = VT_BOOL; pVarResult->boolVal = CPluginClient::GetInstance()->IsAcceptableAdsEnabled() ? VARIANT_TRUE : VARIANT_FALSE; } } break; case dispatchID_SetAcceptableAdsEnabled: { if (pDispparams->cArgs != 1) { return DISP_E_BADPARAMCOUNT; } if (pDispparams->rgvarg[0].vt != VT_BOOL) { return DISP_E_TYPEMISMATCH; } if (pDispparams->rgvarg[0].boolVal != VARIANT_FALSE) { CPluginClient* client = CPluginClient::GetInstance(); client->AddSubscription(client->GetPref(L"subscriptions_exceptionsurl", L"")); } else { CPluginClient* client = CPluginClient::GetInstance(); client->RemoveSubscription(client->GetPref(L"subscriptions_exceptionsurl", L"")); } } break; case dispatchID_IsUpdate: { if (pDispparams->cArgs != 0) { return DISP_E_BADPARAMCOUNT; } if (pVarResult) { pVarResult->vt = VT_BOOL; pVarResult->boolVal = CPluginClient::GetInstance()->GetPref(L"displayUpdatePage", false) ? VARIANT_TRUE : VARIANT_FALSE; } } break; default: return DISP_E_MEMBERNOTFOUND; break; } } catch (...) { return E_FAIL; } return S_OK; }
string ToString(const ISC_STRING &msg) { return ToString(ToWstring(msg)); }
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(tag, L"id:" + ToWstring(id), ToWstring(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(tag, L"id:" + ToWstring(id), ToWstring(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(tag, L"class:" + ToWstring(className), ToWstring(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 + L"HideEl::Found (?/class) filter:" + ToWString(classIt->second.m_filterText)); CPluginDebug::DebugResultHiding(tag, L"class:" + ToWstring(className), ToWstring(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(tag, L"-", ToWstring(tagIt->second.m_filterText)); #endif return true; } } } return false; }
bool CPluginFilter::IsElementHidden(const std::wstring& tag, IHTMLElement* pEl, const std::wstring& domain, const std::wstring& indent) const { std::wstring id; CComBSTR idBstr; if (SUCCEEDED(pEl->get_id(&idBstr)) && idBstr) { id = ToWstring(idBstr); } std::wstring classNames; CComBSTR classNamesBstr; if (SUCCEEDED(pEl->get_className(&classNamesBstr)) && classNamesBstr) { classNames = ToWstring(classNamesBstr); } CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); { // Search tag/id filters if (!id.empty()) { auto idItEnum = m_elementHideTagsId.equal_range(std::make_pair(tag, id)); for (auto idIt = idItEnum.first; idIt != idItEnum.second; ++idIt) { if (idIt->second.IsMatchFilterElementHide(pEl)) { #ifdef ENABLE_DEBUG_RESULT DEBUG_HIDE_EL(indent + L"HideEl::Found (tag/id) filter:" + idIt->second.m_filterText); CPluginDebug::DebugResultHiding(tag, L"id:" + id, idIt->second.m_filterText); #endif return true; } } // Search general id idItEnum = m_elementHideTagsId.equal_range(std::make_pair(L"", id)); for (auto idIt = idItEnum.first; idIt != idItEnum.second; ++idIt) { if (idIt->second.IsMatchFilterElementHide(pEl)) { #ifdef ENABLE_DEBUG_RESULT DEBUG_HIDE_EL(indent + L"HideEl::Found (?/id) filter:" + idIt->second.m_filterText); CPluginDebug::DebugResultHiding(tag, L"id:" + id, idIt->second.m_filterText); #endif return true; } } } // Search tag/className filters if (!classNames.empty()) { wchar_t* nextToken = nullptr; const wchar_t* token = wcstok_s(&classNames[0], L" \t\n\r", &nextToken); while (token != nullptr) { std::wstring className(token); auto classItEnum = m_elementHideTagsClass.equal_range(std::make_pair(tag, className)); for (auto classIt = classItEnum.first; classIt != classItEnum.second; ++classIt) { if (classIt->second.IsMatchFilterElementHide(pEl)) { #ifdef ENABLE_DEBUG_RESULT DEBUG_HIDE_EL(indent + L"HideEl::Found (tag/class) filter:" + classIt->second.m_filterText); CPluginDebug::DebugResultHiding(tag, L"class:" + className, classIt->second.m_filterText); #endif return true; } } // Search general class name classItEnum = m_elementHideTagsClass.equal_range(std::make_pair(L"", className)); for (auto classIt = classItEnum.first; classIt != classItEnum.second; ++ classIt) { if (classIt->second.IsMatchFilterElementHide(pEl)) { #ifdef ENABLE_DEBUG_RESULT DEBUG_HIDE_EL(indent + L"HideEl::Found (?/class) filter:" + classIt->second.m_filterText); CPluginDebug::DebugResultHiding(tag, L"class:" + className, classIt->second.m_filterText); #endif return true; } } token = wcstok_s(nullptr, L" \t\n\r", &nextToken); } } // Search tag filters auto tagItEnum = m_elementHideTags.equal_range(tag); for (auto tagIt = tagItEnum.first; tagIt != tagItEnum.second; ++tagIt) { if (tagIt->second.IsMatchFilterElementHide(pEl)) { #ifdef ENABLE_DEBUG_RESULT DEBUG_HIDE_EL(indent + L"HideEl::Found (tag) filter:" + tagIt->second.m_filterText); CPluginDebug::DebugResultHiding(tag, L"-", tagIt->second.m_filterText); #endif return true; } } } return false; }
bool CFilterElementHide::IsMatchFilterElementHide(IHTMLElement* pEl) const { HRESULT hr; /* * If a tag id is specified, it must match */ if (!m_tagId.empty()) { CComBSTR idBstr; if (FAILED(pEl->get_id(&idBstr)) || !idBstr || m_tagId != ToWstring(idBstr)) { return false; } } /* * If a class name is specified, it must match */ if (!m_tagClassName.empty()) { CComBSTR classNameListBstr; hr = pEl->get_className(&classNameListBstr); if (FAILED(hr) || !classNameListBstr) { return false; // We can't match a class name if there's no class name } std::wstring classNameList(ToWstring(classNameListBstr)); if (classNameList.empty()) { return false; } // TODO: Consider case of multiple classes. (m_tagClassName can be something like "foo.bar") /* * Match when 'm_tagClassName' appears as a token within classNameList */ bool foundMatch = false; wchar_t* nextToken = nullptr; const wchar_t* token = wcstok_s(&classNameList[0], L" ", &nextToken); while (token != nullptr) { if (std::wstring(token) == m_tagClassName) { foundMatch = true; break; } token = wcstok_s(nullptr, L" ", &nextToken); } if (!foundMatch) { return false; } } /* * If a tag name is specified, it must match */ if (!m_tag.empty()) { CComBSTR tagNameBstr; if (FAILED(pEl->get_tagName(&tagNameBstr)) || !tagNameBstr) { return false; } if (m_tag != ToLowerString(ToWstring(tagNameBstr))) { return false; } } /* * Match each attribute */ for (auto attrIt = m_attributeSelectors.begin(); attrIt != m_attributeSelectors.end(); ++attrIt) { std::wstring value; bool attrFound = false; if (attrIt->m_type == CFilterElementHideAttrType::STYLE) { CComPtr<IHTMLStyle> pStyle; if (SUCCEEDED(pEl->get_style(&pStyle)) && pStyle) { CComBSTR styleBstr; if (SUCCEEDED(pStyle->get_cssText(&styleBstr)) && styleBstr) { value = ToLowerString(ToWstring(styleBstr)); attrFound = true; } } } else if (attrIt->m_type == CFilterElementHideAttrType::CLASS) { CComBSTR classNamesBstr; if (SUCCEEDED(pEl->get_className(&classNamesBstr)) && classNamesBstr) { value = ToWstring(classNamesBstr); attrFound = true; } } else if (attrIt->m_type == CFilterElementHideAttrType::ID) { CComBSTR idBstr; if (SUCCEEDED(pEl->get_id(&idBstr)) && idBstr) { value = ToWstring(idBstr); attrFound = true; } } else { CComBSTR attrArgument(attrIt->m_attr.length(), attrIt->m_attr.c_str()); auto x = GetHtmlElementAttribute(*pEl, attrArgument); attrFound = x.isAttributeFound; if (attrFound) { value = x.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.compare(0, attrIt->m_value.length(), attrIt->m_value) != 0) return false; } else if (attrIt->m_pos == CFilterElementHideAttrPos::ENDING) { size_t valueLength = value.length(); size_t attrLength = attrIt->m_value.length(); if (valueLength < attrLength) return false; if (value.compare(valueLength - attrLength, attrLength, attrIt->m_value) != 0) return false; } else if (attrIt->m_pos == CFilterElementHideAttrPos::ANYWHERE) { if (value.find(attrIt->m_value) == std::wstring::npos) return false; } else if (attrIt->m_value.empty()) { 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; }