Index: src/plugin/PluginClass.cpp |
=================================================================== |
--- a/src/plugin/PluginClass.cpp |
+++ b/src/plugin/PluginClass.cpp |
@@ -394,6 +394,7 @@ |
} |
if (s_instances.empty()) |
{ |
+ // TODO: Explicitly releasing a resource when a container becomes empty looks like a job better suited for shared_ptr |
CPluginClientFactory::ReleaseMimeFilterClientInstance(); |
} |
} |
@@ -527,6 +528,11 @@ |
DEBUG_GENERAL("ShowStatusBar end"); |
} |
+/* |
+ * #1163 This class is the implementation for method DISPID_BEFORENAVIGATE2 in CPluginClass::Invoke. |
+ * - It validates and convertes its own arguments, rather than unifying them in the Invoke body. |
+ * - It's declared void and not HRESULT, so DISPID_BEFORENAVIGATE2 can only return S_OK. |
+ */ |
void CPluginClass::BeforeNavigate2(DISPPARAMS* pDispParams) |
{ |
@@ -595,6 +601,13 @@ |
#endif |
} |
} |
+ |
+/* |
+ * #1163 implements behavior for method DISPID_WINDOWSTATECHANGED in CPluginClass::Invoke |
+ * - should validate and convert arguments in Invoke, not here |
+ * - does not validate number of arguments before indexing into 'rgvarg' |
+ * - does not validate type of argument before using its value |
+ */ |
STDMETHODIMP CPluginClass::OnTabChanged(DISPPARAMS* pDispParams, WORD wFlags) |
{ |
DEBUG_GENERAL("Tab changed"); |
@@ -605,163 +618,169 @@ |
if (it == s_threadInstances.end()) |
{ |
s_threadInstances[::GetCurrentThreadId()] = this; |
- |
- |
if (!m_isInitializedOk) |
{ |
m_isInitializedOk = true; |
- if (!InitObject(true)) |
- { |
- // Unadvice(); |
- } |
+ InitObject(true); |
UpdateStatusBar(); |
} |
} |
} |
notificationMessage.Hide(); |
DEBUG_GENERAL("Tab change end"); |
- return VARIANT_TRUE; |
+ return S_OK; |
} |
// This gets called whenever there's a browser event |
+// ENTRY POINT |
STDMETHODIMP CPluginClass::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pvarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr) |
{ |
- WCHAR tmp[256]; |
- wsprintf(tmp, L"Invoke: %d\n", dispidMember); |
- DEBUG_GENERAL(tmp); |
- switch (dispidMember) |
+ try |
{ |
+ WCHAR tmp[256]; |
+ wsprintf(tmp, L"Invoke: %d\n", dispidMember); |
+ DEBUG_GENERAL(tmp); |
+ switch (dispidMember) |
+ { |
+ case DISPID_WINDOWSTATECHANGED: |
+ { |
+ // #1163 should validate and convert arguments here |
+ return OnTabChanged(pDispParams, wFlags); |
+ } |
- case DISPID_WINDOWSTATECHANGED: |
- return OnTabChanged(pDispParams, wFlags); |
- break; |
- case DISPID_HTMLDOCUMENTEVENTS2_ONBEFOREUPDATE: |
- return VARIANT_TRUE; |
- break; |
+ case DISPID_HTMLDOCUMENTEVENTS2_ONBEFOREUPDATE: |
+ break; |
- case DISPID_HTMLDOCUMENTEVENTS2_ONCLICK: |
- return VARIANT_TRUE; |
- break; |
+ case DISPID_HTMLDOCUMENTEVENTS2_ONCLICK: |
+ break; |
- case DISPID_EVMETH_ONLOAD: |
- DEBUG_NAVI("Navi::OnLoad") |
- return VARIANT_TRUE; |
- break; |
+ case DISPID_EVMETH_ONLOAD: |
+ DEBUG_NAVI("Navi::OnLoad") |
+ break; |
- case DISPID_EVMETH_ONCHANGE: |
- return VARIANT_TRUE; |
+ case DISPID_EVMETH_ONCHANGE: |
+ break; |
- case DISPID_EVMETH_ONMOUSEDOWN: |
- return VARIANT_TRUE; |
+ case DISPID_EVMETH_ONMOUSEDOWN: |
+ break; |
- case DISPID_EVMETH_ONMOUSEENTER: |
- return VARIANT_TRUE; |
+ case DISPID_EVMETH_ONMOUSEENTER: |
+ break; |
- case DISPID_IHTMLIMGELEMENT_START: |
- return VARIANT_TRUE; |
+ case DISPID_IHTMLIMGELEMENT_START: |
+ break; |
- case STDDISPID_XOBJ_ERRORUPDATE: |
- return VARIANT_TRUE; |
+ case STDDISPID_XOBJ_ERRORUPDATE: |
+ break; |
- case STDDISPID_XOBJ_ONPROPERTYCHANGE: |
- return VARIANT_TRUE; |
+ case STDDISPID_XOBJ_ONPROPERTYCHANGE: |
+ break; |
- case DISPID_READYSTATECHANGE: |
- DEBUG_NAVI("Navi::ReadyStateChange") |
- return VARIANT_TRUE; |
+ case DISPID_READYSTATECHANGE: |
+ DEBUG_NAVI("Navi::ReadyStateChange"); |
+ break; |
- case DISPID_BEFORENAVIGATE: |
- DEBUG_NAVI("Navi::BeforeNavigate") |
- return VARIANT_TRUE; |
- case DISPID_COMMANDSTATECHANGE: |
- if (m_hPaneWnd == NULL) |
- { |
- CreateStatusBarPane(); |
- } |
- else |
- { |
- if (CPluginClient::GetInstance()->GetIEVersion() > 6) |
+ case DISPID_BEFORENAVIGATE: |
+ DEBUG_NAVI("Navi::BeforeNavigate"); |
+ break; |
+ |
+ case DISPID_COMMANDSTATECHANGE: |
+ if (m_hPaneWnd == NULL) |
{ |
- RECT rect; |
- BOOL rectRes = GetClientRect(m_hStatusBarWnd, &rect); |
- if (rectRes == TRUE) |
+ CreateStatusBarPane(); |
+ } |
+ else |
+ { |
+ if (CPluginClient::GetInstance()->GetIEVersion() > 6) |
{ |
- MoveWindow(m_hPaneWnd, rect.right - 200, 0, m_nPaneWidth, rect.bottom - rect.top, TRUE); |
+ RECT rect; |
+ BOOL rectRes = GetClientRect(m_hStatusBarWnd, &rect); |
+ if (rectRes == TRUE) |
+ { |
+ MoveWindow(m_hPaneWnd, rect.right - 200, 0, m_nPaneWidth, rect.bottom - rect.top, TRUE); |
+ } |
+ } |
+ } |
+ break; |
+ |
+ case DISPID_STATUSTEXTCHANGE: |
+ break; |
+ |
+ case DISPID_BEFORENAVIGATE2: |
+ { |
+ // #1163 should validate and convert parameters here |
+ BeforeNavigate2(pDispParams); |
+ } |
+ break; |
+ |
+ case DISPID_DOWNLOADBEGIN: |
+ { |
+ DEBUG_NAVI("Navi::Download Begin") |
+ } |
+ break; |
+ |
+ case DISPID_DOWNLOADCOMPLETE: |
+ { |
+ DEBUG_NAVI("Navi::Download Complete"); |
+ CComQIPtr<IWebBrowser2> browser = GetBrowser(); |
+ if (browser) |
+ { |
+ m_tab->OnDownloadComplete(browser); |
} |
- } |
- } |
- break; |
- case DISPID_STATUSTEXTCHANGE: |
- break; |
+ } |
+ break; |
- case DISPID_BEFORENAVIGATE2: |
- BeforeNavigate2(pDispParams); |
- break; |
- |
- case DISPID_DOWNLOADBEGIN: |
- { |
- DEBUG_NAVI("Navi::Download Begin") |
- } |
- break; |
- |
- case DISPID_DOWNLOADCOMPLETE: |
- { |
- DEBUG_NAVI("Navi::Download Complete") |
- |
+ case DISPID_DOCUMENTCOMPLETE: |
+ { |
+ DEBUG_NAVI("Navi::Document Complete"); |
CComQIPtr<IWebBrowser2> browser = GetBrowser(); |
- if (browser) |
- { |
- m_tab->OnDownloadComplete(browser); |
- } |
- } |
- break; |
- |
- case DISPID_DOCUMENTCOMPLETE: |
- { |
- DEBUG_NAVI("Navi::Document Complete") |
- |
- CComQIPtr<IWebBrowser2> browser = GetBrowser(); |
- |
- if (browser && pDispParams->cArgs >= 2 && pDispParams->rgvarg[1].vt == VT_DISPATCH) |
- { |
- CComQIPtr<IWebBrowser2> pBrowser = pDispParams->rgvarg[1].pdispVal; |
- if (pBrowser) |
+ if (browser && pDispParams->cArgs >= 2 && pDispParams->rgvarg[1].vt == VT_DISPATCH) |
{ |
- CString url; |
- CComBSTR bstrUrl; |
- if (SUCCEEDED(pBrowser->get_LocationURL(&bstrUrl)) && ::SysStringLen(bstrUrl) > 0) |
+ CComQIPtr<IWebBrowser2> pBrowser = pDispParams->rgvarg[1].pdispVal; |
+ if (pBrowser) |
{ |
- url = bstrUrl; |
- |
- CPluginClient::UnescapeUrl(url); |
- |
- m_tab->OnDocumentComplete(browser, url, browser.IsEqualObject(pBrowser)); |
+ CString url; |
+ CComBSTR bstrUrl; |
+ if (SUCCEEDED(pBrowser->get_LocationURL(&bstrUrl)) && ::SysStringLen(bstrUrl) > 0) |
+ { |
+ url = bstrUrl; |
+ CPluginClient::UnescapeUrl(url); |
+ m_tab->OnDocumentComplete(browser, url, browser.IsEqualObject(pBrowser)); |
+ } |
} |
} |
} |
+ break; |
+ |
+ case DISPID_ONQUIT: |
+ case DISPID_QUIT: |
+ { |
+ Unadvice(); |
+ } |
+ break; |
+ |
+ default: |
+ { |
+ CString did; |
+ did.Format(L"DispId:%u", dispidMember); |
+ |
+ DEBUG_NAVI(L"Navi::Default " + did) |
+ } |
+ /* |
+ * Ordinarily a method not dispatched should return DISP_E_MEMBERNOTFOUND. |
+ * As a conservative initial change, we leave it behaving as before, |
+ * which is to do nothing and return S_OK. |
+ */ |
+ // do nothing |
+ break; |
} |
- break; |
- |
- case DISPID_ONQUIT: |
- case DISPID_QUIT: |
- { |
- Unadvice(); |
- } |
- break; |
- |
- default: |
- { |
- CString did; |
- did.Format(L"DispId:%u", dispidMember); |
- |
- DEBUG_NAVI(L"Navi::Default " + did) |
- } |
- |
- // do nothing |
- break; |
} |
- |
- return VARIANT_TRUE; |
+ catch(...) |
+ { |
+ DEBUG_GENERAL( "Caught unknown exception in CPluginClass::Invoke" ); |
+ return E_FAIL; |
+ } |
+ return S_OK; |
} |
bool CPluginClass::InitObject(bool bBHO) |