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

Unified Diff: src/plugin/PluginTabBase.cpp

Issue 5447868882092032: Issue 1793 - check whether the frame is whitelisted before injecting CSS (Closed)
Patch Set: add link Created Oct. 28, 2015, 10:32 a.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
« src/engine/Main.cpp ('K') | « src/plugin/AdblockPlusClient.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/plugin/PluginTabBase.cpp
diff --git a/src/plugin/PluginTabBase.cpp b/src/plugin/PluginTabBase.cpp
index 3ac26f23bfca300ac710654ca2b406b6bd1be5c1..4acc8242924fc788481bdf495a08dc707300fdfc 100644
--- a/src/plugin/PluginTabBase.cpp
+++ b/src/plugin/PluginTabBase.cpp
@@ -1,394 +1,441 @@
-/*
- * This file is part of Adblock Plus <https://adblockplus.org/>,
- * Copyright (C) 2006-2015 Eyeo GmbH
- *
- * Adblock Plus is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 3 as
- * published by the Free Software Foundation.
- *
- * Adblock Plus is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "PluginStdAfx.h"
-#include "AdblockPlusClient.h"
-#include "PluginClientBase.h"
-#include "PluginSettings.h"
-#include "AdblockPlusDomTraverser.h"
-#include "PluginTabBase.h"
-#include "IeVersion.h"
-#include <Mshtmhst.h>
-
-CPluginTabBase::CPluginTabBase(CPluginClass* plugin)
- : m_plugin(plugin)
- , m_isActivated(false)
- , m_continueThreadRunning(true)
-{
- m_filter = std::auto_ptr<CPluginFilter>(new CPluginFilter());
- m_filter->hideFiltersLoadedEvent = CreateEvent(NULL, true, false, NULL);
-
- CPluginClient* client = CPluginClient::GetInstance();
- if (AdblockPlus::IE::InstalledMajorVersion() < 10)
- {
- m_isActivated = true;
- }
-
- try
- {
- m_thread = std::thread(&CPluginTabBase::ThreadProc, this);
- }
- catch (const std::system_error& ex)
- {
- DEBUG_SYSTEM_EXCEPTION(ex, PLUGIN_ERROR_THREAD, PLUGIN_ERROR_TAB_THREAD_CREATE_PROCESS,
- "Tab::Thread - Failed to create tab thread");
- }
- m_traverser = new CPluginDomTraverser(static_cast<CPluginTab*>(this));
-}
-
-
-CPluginTabBase::~CPluginTabBase()
-{
- delete m_traverser;
- m_traverser = NULL;
- m_continueThreadRunning = false;
- if (m_thread.joinable()) {
- m_thread.join();
- }
-}
-
-void CPluginTabBase::OnActivate()
-{
- m_isActivated = true;
-}
-
-
-void CPluginTabBase::OnUpdate()
-{
- m_isActivated = true;
-}
-
-namespace
-{
- // Entry Point
- void FilterLoader(CPluginTabBase* tabBase)
- {
- try
- {
- tabBase->m_filter->LoadHideFilters(CPluginClient::GetInstance()->GetElementHidingSelectors(tabBase->GetDocumentDomain()));
- SetEvent(tabBase->m_filter->hideFiltersLoadedEvent);
- }
- catch (...)
- {
- // As a thread-main function, we truncate any C++ exception.
- }
- }
-}
-
-void CPluginTabBase::OnNavigate(const std::wstring& url)
-{
- SetDocumentUrl(url);
- ClearFrameCache(GetDocumentDomain());
- std::wstring domainString = GetDocumentDomain();
- ResetEvent(m_filter->hideFiltersLoadedEvent);
- try
- {
- std::thread filterLoaderThread(&FilterLoader, this);
- filterLoaderThread.detach(); // TODO: but actually we should wait for the thread in the dtr.
- }
- catch (const std::system_error& ex)
- {
- DEBUG_SYSTEM_EXCEPTION(ex, PLUGIN_ERROR_THREAD, PLUGIN_ERROR_MAIN_THREAD_CREATE_PROCESS,
- "Class::Thread - Failed to start filter loader thread");
- }
- m_traverser->ClearCache();
-}
-
-namespace
-{
- /**
- * Determine if the HTML file is one of ours.
- * The criterion is that it appear in the "html/templates" folder within our installation.
- *
- * Warning: This function may fail if the argument is not a "file://" URL.
- * This is occasionally the case in circumstances yet to be characterized.
- */
- bool IsOurHtmlFile(const std::wstring& url)
- {
- // Declared static because the value is derived from an installation directory, which won't change during run-time.
- static auto dir = FileUrl(HtmlFolderPath());
-
- DEBUG_GENERAL([&]() -> std::wstring {
- std::wstring log = L"InjectABP. Current URL: ";
- log += url;
- log += L", template directory URL: ";
- log += dir;
- return log;
- }());
-
- /*
- * The length check here is defensive, in case the document URL is truncated for some reason.
- */
- if (url.length() < 5)
- {
- // We can't match ".html" at the end of the URL if it's too short.
- return false;
- }
- auto urlCstr = url.c_str();
- // Check the prefix to match our directory
- // Check the suffix to be an HTML file
- return (_wcsnicmp(urlCstr, dir.c_str(), dir.length()) == 0) &&
- (_wcsnicmp(urlCstr + url.length() - 5, L".html", 5) == 0);
- }
-}
-
-void CPluginTabBase::InjectABP(IWebBrowser2* browser)
-{
- CriticalSection::Lock lock(m_csInject);
- auto url = GetDocumentUrl();
- if (!IsOurHtmlFile(url))
- {
- DEBUG_GENERAL(L"InjectABP. Not injecting");
- return;
- }
- DEBUG_GENERAL(L"InjectABP. Injecting");
- CComPtr<IDispatch> pDocDispatch;
- browser->get_Document(&pDocDispatch);
- CComQIPtr<IHTMLDocument2> pDoc2 = pDocDispatch;
- if (!pDoc2)
- {
- DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to QI document");
- return;
- }
- CComPtr<IHTMLWindow2> pWnd2;
- pDoc2->get_parentWindow(&pWnd2);
- if (!pWnd2)
- {
- DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to get parent window");
- return;
- }
- CComQIPtr<IDispatchEx> pWndEx = pWnd2;
- if (!pWndEx)
- {
- DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to QI dispatch");
- return;
- }
- // Create "Settings" object in JavaScript.
- // A method call of "Settings" in JavaScript, transfered to "Invoke" of m_pluginUserSettings
- DISPID dispid;
- HRESULT hr = pWndEx->GetDispID(L"Settings", fdexNameEnsure, &dispid);
- if (FAILED(hr))
- {
- DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to get dispatch");
- return;
- }
- CComVariant var((IDispatch*)&m_pluginUserSettings);
-
- DEBUG_GENERAL("Injecting");
-
- DISPPARAMS params;
- params.cArgs = 1;
- params.cNamedArgs = 0;
- params.rgvarg = &var;
- params.rgdispidNamedArgs = 0;
- hr = pWndEx->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF, &params, 0, 0, 0);
- DEBUG_GENERAL("Invoke");
- if (FAILED(hr))
- {
- DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to create Settings in JavaScript");
- }
-}
-
-void CPluginTabBase::OnDownloadComplete(IWebBrowser2* browser)
-{
- CPluginClient* client = CPluginClient::GetInstance();
- std::wstring url = GetDocumentUrl();
- if (!client->IsWhitelistedUrl(url) && !client->IsElemhideWhitelistedOnDomain(url))
- {
- m_traverser->TraverseDocument(browser, GetDocumentDomain(), GetDocumentUrl());
- }
- InjectABP(browser);
-}
-
-void CPluginTabBase::OnDocumentComplete(IWebBrowser2* browser, const std::wstring& url, bool isDocumentBrowser)
-{
- std::wstring documentUrl = GetDocumentUrl();
-
- if (isDocumentBrowser)
- {
- if (url != documentUrl)
- {
- SetDocumentUrl(url);
- }
- InjectABP(browser);
- }
- CString urlLegacy = ToCString(url);
- if (urlLegacy.Left(6) != "res://")
- {
- // Get document
- CComPtr<IDispatch> pDocDispatch;
- HRESULT hr = browser->get_Document(&pDocDispatch);
- if (FAILED(hr) || !pDocDispatch)
- {
- return;
- }
-
- CComQIPtr<IHTMLDocument2> pDoc = pDocDispatch;
- if (!pDoc)
- {
- return;
- }
- CComPtr<IOleObject> pOleObj;
-
- pDocDispatch->QueryInterface(IID_IOleObject, (void**)&pOleObj);
-
-
- CComPtr<IOleClientSite> pClientSite;
- pOleObj->GetClientSite(&pClientSite);
- if (pClientSite != NULL)
- {
- CComPtr<IDocHostUIHandler> docHostUIHandler;
- pClientSite->QueryInterface(IID_IDocHostUIHandler, (void**)&docHostUIHandler);
- if (docHostUIHandler != NULL)
- {
- docHostUIHandler->UpdateUI();
- }
- }
- }
-}
-
-std::wstring CPluginTabBase::GetDocumentDomain()
-{
- std::wstring domain;
-
- m_criticalSection.Lock();
- {
- domain = m_documentDomain;
- }
- m_criticalSection.Unlock();
-
- return domain;
-}
-
-void CPluginTabBase::SetDocumentUrl(const std::wstring& url)
-{
- m_criticalSection.Lock();
- {
- m_documentUrl = url;
- m_documentDomain = CAdblockPlusClient::GetInstance()->GetHostFromUrl(url);
- }
- m_criticalSection.Unlock();
-}
-
-std::wstring CPluginTabBase::GetDocumentUrl()
-{
- std::wstring url;
-
- m_criticalSection.Lock();
- {
- url = m_documentUrl;
- }
- m_criticalSection.Unlock();
-
- return url;
-}
-
-
-// ============================================================================
-// Frame caching
-// ============================================================================
-bool CPluginTabBase::IsFrameCached(const std::wstring& url)
-{
- bool isFrame;
-
- m_criticalSectionCache.Lock();
- {
- isFrame = m_cacheFrames.find(url) != m_cacheFrames.end();
- }
- m_criticalSectionCache.Unlock();
-
- return isFrame;
-}
-
-void CPluginTabBase::CacheFrame(const std::wstring& url)
-{
- m_criticalSectionCache.Lock();
- {
- m_cacheFrames.insert(url);
- }
- m_criticalSectionCache.Unlock();
-}
-
-void CPluginTabBase::ClearFrameCache(const std::wstring& domain)
-{
- m_criticalSectionCache.Lock();
- {
- if (domain.empty() || domain != m_cacheDomain)
- {
- m_cacheFrames.clear();
- m_cacheDomain = domain;
- }
- }
- m_criticalSectionCache.Unlock();
-}
-
-void CPluginTabBase::ThreadProc()
-{
- // Force loading/creation of settings
- CPluginSettings::GetInstance()->SetWorkingThreadId();
-
- std::string message =
- "================================================================================\n"
- "TAB THREAD process=";
- message += std::to_string(::GetCurrentProcessId());
- message + " thread=";
- message += std::to_string(::GetCurrentThreadId());
- message +=
- "\n"
- "================================================================================";
- DEBUG_GENERAL(message);
-
- // --------------------------------------------------------------------
- // Tab loop
- // --------------------------------------------------------------------
-
- DWORD loopCount = 0;
- DWORD tabLoopIteration = 1;
-
- while (this->m_continueThreadRunning)
- {
-#ifdef ENABLE_DEBUG_THREAD
- CStringA sTabLoopIteration;
- sTabLoopIteration.Format("%u", tabLoopIteration);
-
- DEBUG_THREAD("--------------------------------------------------------------------------------")
- DEBUG_THREAD("Loop iteration " + sTabLoopIteration);
- DEBUG_THREAD("--------------------------------------------------------------------------------")
-#endif
- this->m_isActivated = false;
-
- // --------------------------------------------------------------------
- // End loop
- // --------------------------------------------------------------------
-
- // Sleep loop
- while (this->m_continueThreadRunning && !this->m_isActivated && (++loopCount % (TIMER_THREAD_SLEEP_TAB_LOOP / 50)) != 0)
- {
- // Post async plugin error
- CPluginError pluginError;
- if (LogQueue::PopFirstPluginError(pluginError))
- {
- LogQueue::LogPluginError(pluginError.GetErrorCode(), pluginError.GetErrorId(), pluginError.GetErrorSubid(), pluginError.GetErrorDescription(), true, pluginError.GetProcessId(), pluginError.GetThreadId());
- }
-
- // Non-hanging sleep
- Sleep(50);
- }
-
- tabLoopIteration++;
- }
-}
+/*
+ * This file is part of Adblock Plus <https://adblockplus.org/>,
+ * Copyright (C) 2006-2015 Eyeo GmbH
+ *
+ * Adblock Plus is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Adblock Plus is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "PluginStdAfx.h"
+#include "AdblockPlusClient.h"
+#include "PluginClientBase.h"
+#include "PluginSettings.h"
+#include "AdblockPlusDomTraverser.h"
+#include "PluginTabBase.h"
+#include "IeVersion.h"
+#include "../shared/Utils.h"
+#include <Mshtmhst.h>
+
+CPluginTabBase::CPluginTabBase(CPluginClass* plugin)
+ : m_plugin(plugin)
+ , m_isActivated(false)
+ , m_continueThreadRunning(true)
+{
+ m_filter = std::auto_ptr<CPluginFilter>(new CPluginFilter());
+ m_filter->hideFiltersLoadedEvent = CreateEvent(NULL, true, false, NULL);
+
+ CPluginClient* client = CPluginClient::GetInstance();
+ if (AdblockPlus::IE::InstalledMajorVersion() < 10)
+ {
+ m_isActivated = true;
+ }
+
+ try
+ {
+ m_thread = std::thread(&CPluginTabBase::ThreadProc, this);
+ }
+ catch (const std::system_error& ex)
+ {
+ DEBUG_SYSTEM_EXCEPTION(ex, PLUGIN_ERROR_THREAD, PLUGIN_ERROR_TAB_THREAD_CREATE_PROCESS,
+ "Tab::Thread - Failed to create tab thread");
+ }
+ m_traverser = new CPluginDomTraverser(static_cast<CPluginTab*>(this));
+}
+
+
+CPluginTabBase::~CPluginTabBase()
+{
+ delete m_traverser;
+ m_traverser = NULL;
+ m_continueThreadRunning = false;
+ if (m_thread.joinable()) {
+ m_thread.join();
+ }
+}
+
+void CPluginTabBase::OnActivate()
+{
+ m_isActivated = true;
+}
+
+
+void CPluginTabBase::OnUpdate()
+{
+ m_isActivated = true;
+}
+
+namespace
+{
+ // Entry Point
+ void FilterLoader(CPluginTabBase* tabBase)
+ {
+ try
+ {
+ tabBase->m_filter->LoadHideFilters(CPluginClient::GetInstance()->GetElementHidingSelectors(tabBase->GetDocumentDomain()));
+ SetEvent(tabBase->m_filter->hideFiltersLoadedEvent);
+ }
+ catch (...)
+ {
+ // As a thread-main function, we truncate any C++ exception.
+ }
+ }
+}
+
+void CPluginTabBase::OnNavigate(const std::wstring& url)
+{
+ SetDocumentUrl(url);
+ ClearFrameCache(GetDocumentDomain());
+ std::wstring domainString = GetDocumentDomain();
+ ResetEvent(m_filter->hideFiltersLoadedEvent);
+ try
+ {
+ std::thread filterLoaderThread(&FilterLoader, this);
+ filterLoaderThread.detach(); // TODO: but actually we should wait for the thread in the dtr.
+ }
+ catch (const std::system_error& ex)
+ {
+ DEBUG_SYSTEM_EXCEPTION(ex, PLUGIN_ERROR_THREAD, PLUGIN_ERROR_MAIN_THREAD_CREATE_PROCESS,
+ "Class::Thread - Failed to start filter loader thread");
+ }
+ m_traverser->ClearCache();
+}
+
+namespace
+{
+ /**
+ * Determine if the HTML file is one of ours.
+ * The criterion is that it appear in the "html/templates" folder within our installation.
+ *
+ * Warning: This function may fail if the argument is not a "file://" URL.
+ * This is occasionally the case in circumstances yet to be characterized.
+ */
+ bool IsOurHtmlFile(const std::wstring& url)
+ {
+ // Declared static because the value is derived from an installation directory, which won't change during run-time.
+ static auto dir = FileUrl(HtmlFolderPath());
+
+ DEBUG_GENERAL([&]() -> std::wstring {
+ std::wstring log = L"InjectABP. Current URL: ";
+ log += url;
+ log += L", template directory URL: ";
+ log += dir;
+ return log;
+ }());
+
+ /*
+ * The length check here is defensive, in case the document URL is truncated for some reason.
+ */
+ if (url.length() < 5)
+ {
+ // We can't match ".html" at the end of the URL if it's too short.
+ return false;
+ }
+ auto urlCstr = url.c_str();
+ // Check the prefix to match our directory
+ // Check the suffix to be an HTML file
+ return (_wcsnicmp(urlCstr, dir.c_str(), dir.length()) == 0) &&
+ (_wcsnicmp(urlCstr + url.length() - 5, L".html", 5) == 0);
+ }
+}
+
+void CPluginTabBase::InjectABP(IWebBrowser2* browser)
+{
+ CriticalSection::Lock lock(m_csInject);
+ auto url = GetDocumentUrl();
+ if (!IsOurHtmlFile(url))
+ {
+ DEBUG_GENERAL(L"InjectABP. Not injecting");
+ return;
+ }
+ DEBUG_GENERAL(L"InjectABP. Injecting");
+ CComPtr<IDispatch> pDocDispatch;
+ browser->get_Document(&pDocDispatch);
+ CComQIPtr<IHTMLDocument2> pDoc2 = pDocDispatch;
+ if (!pDoc2)
+ {
+ DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to QI document");
+ return;
+ }
+ CComPtr<IHTMLWindow2> pWnd2;
+ pDoc2->get_parentWindow(&pWnd2);
+ if (!pWnd2)
+ {
+ DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to get parent window");
+ return;
+ }
+ CComQIPtr<IDispatchEx> pWndEx = pWnd2;
+ if (!pWndEx)
+ {
+ DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to QI dispatch");
+ return;
+ }
+ // Create "Settings" object in JavaScript.
+ // A method call of "Settings" in JavaScript, transfered to "Invoke" of m_pluginUserSettings
+ DISPID dispid;
+ HRESULT hr = pWndEx->GetDispID(L"Settings", fdexNameEnsure, &dispid);
+ if (FAILED(hr))
+ {
+ DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to get dispatch");
+ return;
+ }
+ CComVariant var((IDispatch*)&m_pluginUserSettings);
+
+ DEBUG_GENERAL("Injecting");
+
+ DISPPARAMS params;
+ params.cArgs = 1;
+ params.cNamedArgs = 0;
+ params.rgvarg = &var;
+ params.rgdispidNamedArgs = 0;
+ hr = pWndEx->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF, &params, 0, 0, 0);
+ DEBUG_GENERAL("Invoke");
+ if (FAILED(hr))
+ {
+ DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to create Settings in JavaScript");
+ }
+}
+
+namespace
+{
Eric 2015/11/14 20:28:13 I don't believe that any of the pointers in the fu
+ ATL::CComPtr<IWebBrowser2> GetParent(IWebBrowser2& browser)
+ {
+ ATL::CComPtr<IDispatch> parentDispatch;
+ if (FAILED(browser.get_Parent(&parentDispatch)) || !parentDispatch)
+ {
+ return nullptr;
+ }
+ // The InternetExplorer application always returns a pointer to itself.
+ // https://msdn.microsoft.com/en-us/library/aa752136(v=vs.85).aspx
+ if (parentDispatch.IsEqualObject(&browser))
+ {
+ return nullptr;
+ }
Eric 2015/11/14 20:28:13 I don't see the need for any of the code in the fu
sergei 2015/11/17 20:16:00 Smart pointers are used to avoid manual calls of R
Eric 2015/11/17 21:00:16 I know what smart pointers for COM objects do. My
sergei 2015/11/17 21:05:23 We should call Release on pointers obtained either
Eric 2015/11/17 22:30:22 This is the real reason. We don't need to manage t
sergei 2015/11/18 10:07:50 I see the point. You are talking that the lifetime
Eric 2015/11/18 15:25:22 I'll concede the point that this is purely defensi
+ ATL::CComQIPtr<IServiceProvider> parentDocumentServiceProvider = parentDispatch;
+ if (!parentDocumentServiceProvider)
+ {
+ return nullptr;
+ }
+ ATL::CComPtr<IWebBrowserApp> webBrowserApp;
+ if (FAILED(parentDocumentServiceProvider->QueryService(IID_IWebBrowserApp, &webBrowserApp)) || !webBrowserApp)
+ {
+ return nullptr;
+ }
+ return ATL::CComQIPtr<IWebBrowser2>(webBrowserApp);
+ }
+
+ bool IsFrameWhiteListed(ATL::CComPtr<IWebBrowser2> frame)
+ {
+ if (!frame)
+ {
+ return false;
+ }
+ auto url = GetLocationUrl(*frame);
+ std::vector<std::string> frameHierarchy;
+ while(frame = GetParent(*frame))
+ {
+ frameHierarchy.push_back(ToUtf8String(GetLocationUrl(*frame)));
+ }
+ CPluginClient* client = CPluginClient::GetInstance();
+ return client->IsWhitelistedUrl(url, frameHierarchy)
+ || client->IsElemhideWhitelistedOnDomain(url, frameHierarchy);
+ }
+}
+
+void CPluginTabBase::OnDownloadComplete(IWebBrowser2* browser)
+{
+ CPluginClient* client = CPluginClient::GetInstance();
+ std::wstring url = GetDocumentUrl();
+ if (!client->IsWhitelistedUrl(url) && !client->IsElemhideWhitelistedOnDomain(url))
+ {
+ m_traverser->TraverseDocument(browser, GetDocumentDomain(), GetDocumentUrl());
+ }
+ InjectABP(browser);
+}
+
+void CPluginTabBase::OnDocumentComplete(IWebBrowser2* browser, const std::wstring& url, bool isDocumentBrowser)
+{
+ std::wstring documentUrl = GetDocumentUrl();
+
+ if (isDocumentBrowser)
+ {
+ if (url != documentUrl)
+ {
+ SetDocumentUrl(url);
+ }
+ InjectABP(browser);
+ }
+ CString urlLegacy = ToCString(url);
+ if (urlLegacy.Left(6) != "res://")
+ {
+ // Get document
+ CComPtr<IDispatch> pDocDispatch;
+ HRESULT hr = browser->get_Document(&pDocDispatch);
+ if (FAILED(hr) || !pDocDispatch)
+ {
+ return;
+ }
+
+ CComQIPtr<IHTMLDocument2> pDoc = pDocDispatch;
+ if (!pDoc)
+ {
+ return;
+ }
+ CComPtr<IOleObject> pOleObj;
+
+ pDocDispatch->QueryInterface(IID_IOleObject, (void**)&pOleObj);
+
+
+ CComPtr<IOleClientSite> pClientSite;
+ pOleObj->GetClientSite(&pClientSite);
+ if (pClientSite != NULL)
+ {
+ CComPtr<IDocHostUIHandler> docHostUIHandler;
+ pClientSite->QueryInterface(IID_IDocHostUIHandler, (void**)&docHostUIHandler);
+ if (docHostUIHandler != NULL)
+ {
+ docHostUIHandler->UpdateUI();
+ }
+ }
+ }
+}
+
+std::wstring CPluginTabBase::GetDocumentDomain()
+{
+ std::wstring domain;
+
+ m_criticalSection.Lock();
+ {
+ domain = m_documentDomain;
+ }
+ m_criticalSection.Unlock();
+
+ return domain;
+}
+
+void CPluginTabBase::SetDocumentUrl(const std::wstring& url)
+{
+ m_criticalSection.Lock();
+ {
+ m_documentUrl = url;
+ m_documentDomain = CAdblockPlusClient::GetInstance()->GetHostFromUrl(url);
+ }
+ m_criticalSection.Unlock();
+}
+
+std::wstring CPluginTabBase::GetDocumentUrl()
+{
+ std::wstring url;
+
+ m_criticalSection.Lock();
+ {
+ url = m_documentUrl;
+ }
+ m_criticalSection.Unlock();
+
+ return url;
+}
+
+
+// ============================================================================
+// Frame caching
+// ============================================================================
+bool CPluginTabBase::IsFrameCached(const std::wstring& url)
+{
+ bool isFrame;
+
+ m_criticalSectionCache.Lock();
+ {
+ isFrame = m_cacheFrames.find(url) != m_cacheFrames.end();
+ }
+ m_criticalSectionCache.Unlock();
+
+ return isFrame;
+}
+
+void CPluginTabBase::CacheFrame(const std::wstring& url)
+{
+ m_criticalSectionCache.Lock();
+ {
+ m_cacheFrames.insert(url);
+ }
+ m_criticalSectionCache.Unlock();
+}
+
+void CPluginTabBase::ClearFrameCache(const std::wstring& domain)
+{
+ m_criticalSectionCache.Lock();
+ {
+ if (domain.empty() || domain != m_cacheDomain)
+ {
+ m_cacheFrames.clear();
+ m_cacheDomain = domain;
+ }
+ }
+ m_criticalSectionCache.Unlock();
+}
+
+void CPluginTabBase::ThreadProc()
+{
+ // Force loading/creation of settings
+ CPluginSettings::GetInstance()->SetWorkingThreadId();
+
+ std::string message =
+ "================================================================================\n"
+ "TAB THREAD process=";
+ message += std::to_string(::GetCurrentProcessId());
+ message + " thread=";
+ message += std::to_string(::GetCurrentThreadId());
+ message +=
+ "\n"
+ "================================================================================";
+ DEBUG_GENERAL(message);
+
+ // --------------------------------------------------------------------
+ // Tab loop
+ // --------------------------------------------------------------------
+
+ DWORD loopCount = 0;
+ DWORD tabLoopIteration = 1;
+
+ while (this->m_continueThreadRunning)
+ {
+#ifdef ENABLE_DEBUG_THREAD
+ CStringA sTabLoopIteration;
+ sTabLoopIteration.Format("%u", tabLoopIteration);
+
+ DEBUG_THREAD("--------------------------------------------------------------------------------")
+ DEBUG_THREAD("Loop iteration " + sTabLoopIteration);
+ DEBUG_THREAD("--------------------------------------------------------------------------------")
+#endif
+ this->m_isActivated = false;
+
+ // --------------------------------------------------------------------
+ // End loop
+ // --------------------------------------------------------------------
+
+ // Sleep loop
+ while (this->m_continueThreadRunning && !this->m_isActivated && (++loopCount % (TIMER_THREAD_SLEEP_TAB_LOOP / 50)) != 0)
+ {
+ // Post async plugin error
+ CPluginError pluginError;
+ if (LogQueue::PopFirstPluginError(pluginError))
+ {
+ LogQueue::LogPluginError(pluginError.GetErrorCode(), pluginError.GetErrorId(), pluginError.GetErrorSubid(), pluginError.GetErrorDescription(), true, pluginError.GetProcessId(), pluginError.GetThreadId());
+ }
+
+ // Non-hanging sleep
+ Sleep(50);
+ }
+
+ tabLoopIteration++;
+ }
+}
« src/engine/Main.cpp ('K') | « src/plugin/AdblockPlusClient.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld