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

Side by Side Diff: src/plugin/PluginClass.cpp

Issue 6495401389588480: Issue #1173 - add exception handler to CPluginClass::Invoke (Closed)
Patch Set: Created Aug. 6, 2014, 9:32 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #include "PluginStdAfx.h" 1 #include "PluginStdAfx.h"
2 2
3 #include "PluginClass.h" 3 #include "PluginClass.h"
4 #include "PluginSettings.h" 4 #include "PluginSettings.h"
5 #include "PluginSystem.h" 5 #include "PluginSystem.h"
6 #ifdef SUPPORT_FILTER 6 #ifdef SUPPORT_FILTER
7 #include "PluginFilter.h" 7 #include "PluginFilter.h"
8 #endif 8 #endif
9 #include "PluginMimeFilterClient.h" 9 #include "PluginMimeFilterClient.h"
10 #include "PluginClient.h" 10 #include "PluginClient.h"
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 { 387 {
388 s_instances.erase(this); 388 s_instances.erase(this);
389 389
390 std::map<DWORD,CPluginClass*>::iterator it = s_threadInstances.find(::GetC urrentThreadId()); 390 std::map<DWORD,CPluginClass*>::iterator it = s_threadInstances.find(::GetC urrentThreadId());
391 if (it != s_threadInstances.end()) 391 if (it != s_threadInstances.end())
392 { 392 {
393 s_threadInstances.erase(it); 393 s_threadInstances.erase(it);
394 } 394 }
395 if (s_instances.empty()) 395 if (s_instances.empty())
396 { 396 {
397 // AUDIT: Explicitly releasing a resource when a container becomes empty looks like a job better suited for shared_ptr
Oleksandr 2014/08/21 14:49:56 I think it's better to create an issue then to put
Eric 2014/09/29 19:16:44 Well, I don't know what the issue would be yet; I
Oleksandr 2014/10/02 20:44:16 How about TODO: then? On 2014/09/29 19:16:44, Eri
Eric 2014/10/02 23:11:02 OK.
397 CPluginClientFactory::ReleaseMimeFilterClientInstance(); 398 CPluginClientFactory::ReleaseMimeFilterClientInstance();
398 } 399 }
399 } 400 }
400 s_criticalSectionLocal.Unlock(); 401 s_criticalSectionLocal.Unlock();
401 402
402 // Release browser interface 403 // Release browser interface
403 s_criticalSectionBrowser.Lock(); 404 s_criticalSectionBrowser.Lock();
404 { 405 {
405 m_webBrowser2.Release(); 406 m_webBrowser2.Release();
406 } 407 }
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 } 521 }
521 } 522 }
522 else 523 else
523 { 524 {
524 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_STATUSBAR, "Class ::Get statusbar state"); 525 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_STATUSBAR, "Class ::Get statusbar state");
525 } 526 }
526 } 527 }
527 DEBUG_GENERAL("ShowStatusBar end"); 528 DEBUG_GENERAL("ShowStatusBar end");
528 } 529 }
529 530
531 /*
532 * #1163 This class is the implementation for method DISPID_BEFORENAVIGATE2 in C PluginClass::Invoke.
533 * - It validates and convertes its own arguments, rather than unifying them in the Invoke body.
534 * - It's declared void and not HRESULT, so DISPID_BEFORENAVIGATE2 can only retu rn S_OK.
535 */
Oleksandr 2014/08/21 14:49:56 All the comments in this file that start with #116
Eric 2014/09/29 19:16:44 These comments are intended to exist only while #1
Oleksandr 2014/10/02 20:44:16 ok, as long as you'll be able to keep track of the
Eric 2014/10/02 23:11:02 No problem. That's what grep is for.
530 void CPluginClass::BeforeNavigate2(DISPPARAMS* pDispParams) 536 void CPluginClass::BeforeNavigate2(DISPPARAMS* pDispParams)
531 { 537 {
532 538
533 if (pDispParams->cArgs < 7) 539 if (pDispParams->cArgs < 7)
534 { 540 {
535 return; 541 return;
536 } 542 }
537 //Register a mime filter if it's not registered yet 543 //Register a mime filter if it's not registered yet
538 if (s_mimeFilter == NULL) 544 if (s_mimeFilter == NULL)
539 { 545 {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 } 594 }
589 else 595 else
590 { 596 {
591 DEBUG_NAVI(L"Navi::Begin navigation url:" + url) 597 DEBUG_NAVI(L"Navi::Begin navigation url:" + url)
592 598
593 #ifdef SUPPORT_FRAME_CACHING 599 #ifdef SUPPORT_FRAME_CACHING
594 m_tab->CacheFrame(url); 600 m_tab->CacheFrame(url);
595 #endif 601 #endif
596 } 602 }
597 } 603 }
604
605 /*
606 * #1163 implements behavior for method DISPID_WINDOWSTATECHANGED in CPluginClas s::Invoke
607 * - should validate and convert arguments in Invoke, not here
608 * - does not validate number of arguments before indexing into 'rgvarg'
609 * - does not validate type of argument before using its value
610 */
598 STDMETHODIMP CPluginClass::OnTabChanged(DISPPARAMS* pDispParams, WORD wFlags) 611 STDMETHODIMP CPluginClass::OnTabChanged(DISPPARAMS* pDispParams, WORD wFlags)
599 { 612 {
600 DEBUG_GENERAL("Tab changed"); 613 DEBUG_GENERAL("Tab changed");
601 bool newtabshown = pDispParams->rgvarg[1].intVal==3; 614 bool newtabshown = pDispParams->rgvarg[1].intVal==3;
602 if (newtabshown) 615 if (newtabshown)
603 { 616 {
604 std::map<DWORD,CPluginClass*>::const_iterator it = s_threadInstances.find(Ge tCurrentThreadId()); 617 std::map<DWORD,CPluginClass*>::const_iterator it = s_threadInstances.find(Ge tCurrentThreadId());
605 if (it == s_threadInstances.end()) 618 if (it == s_threadInstances.end())
606 { 619 {
607 s_threadInstances[::GetCurrentThreadId()] = this; 620 s_threadInstances[::GetCurrentThreadId()] = this;
608
609
610 if (!m_isInitializedOk) 621 if (!m_isInitializedOk)
611 { 622 {
612 m_isInitializedOk = true; 623 m_isInitializedOk = true;
613 if (!InitObject(true)) 624 InitObject(true);
614 {
615 //» » » » » Unadvice();
616 }
617 UpdateStatusBar(); 625 UpdateStatusBar();
618 } 626 }
619 } 627 }
620 } 628 }
621 notificationMessage.Hide(); 629 notificationMessage.Hide();
622 DEBUG_GENERAL("Tab change end"); 630 DEBUG_GENERAL("Tab change end");
623 return VARIANT_TRUE; 631 return S_OK;
624 } 632 }
625 633
626 // This gets called whenever there's a browser event 634 // This gets called whenever there's a browser event
627 STDMETHODIMP CPluginClass::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, W ORD wFlags, DISPPARAMS* pDispParams, VARIANT* pvarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr) 635 STDMETHODIMP CPluginClass::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, W ORD wFlags, DISPPARAMS* pDispParams, VARIANT* pvarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
628 { 636 {
629 WCHAR tmp[256]; 637 // Entry point exception handler
Oleksandr 2014/08/21 14:49:56 Self-evident, IMHO
Eric 2014/09/29 19:16:44 I mentioned this in another review, but I'd like t
Eric 2014/10/02 23:11:02 Per a suggestion in another review, I'm changing t
630 wsprintf(tmp, L"Invoke: %d\n", dispidMember); 638 try
631 DEBUG_GENERAL(tmp);
632 switch (dispidMember)
633 { 639 {
640 WCHAR tmp[256];
641 wsprintf(tmp, L"Invoke: %d\n", dispidMember);
642 DEBUG_GENERAL(tmp);
643 switch (dispidMember)
644 {
645 case DISPID_WINDOWSTATECHANGED:
646 {
647 // #1163 should validate and convert arguments here
648 return OnTabChanged(pDispParams, wFlags);
649 }
634 650
635 case DISPID_WINDOWSTATECHANGED: 651 case DISPID_HTMLDOCUMENTEVENTS2_ONBEFOREUPDATE:
636 return OnTabChanged(pDispParams, wFlags); 652 break;
637 break;
638 case DISPID_HTMLDOCUMENTEVENTS2_ONBEFOREUPDATE:
639 return VARIANT_TRUE;
640 break;
641 653
642 case DISPID_HTMLDOCUMENTEVENTS2_ONCLICK: 654 case DISPID_HTMLDOCUMENTEVENTS2_ONCLICK:
643 return VARIANT_TRUE; 655 break;
644 break;
645 656
646 case DISPID_EVMETH_ONLOAD: 657 case DISPID_EVMETH_ONLOAD:
647 DEBUG_NAVI("Navi::OnLoad") 658 DEBUG_NAVI("Navi::OnLoad")
648 return VARIANT_TRUE; 659 break;
649 break;
650 660
651 case DISPID_EVMETH_ONCHANGE: 661 case DISPID_EVMETH_ONCHANGE:
652 return VARIANT_TRUE; 662 break;
653 663
654 case DISPID_EVMETH_ONMOUSEDOWN: 664 case DISPID_EVMETH_ONMOUSEDOWN:
655 return VARIANT_TRUE; 665 break;
656 666
657 case DISPID_EVMETH_ONMOUSEENTER: 667 case DISPID_EVMETH_ONMOUSEENTER:
658 return VARIANT_TRUE; 668 break;
659 669
660 case DISPID_IHTMLIMGELEMENT_START: 670 case DISPID_IHTMLIMGELEMENT_START:
661 return VARIANT_TRUE; 671 break;
662 672
663 case STDDISPID_XOBJ_ERRORUPDATE: 673 case STDDISPID_XOBJ_ERRORUPDATE:
664 return VARIANT_TRUE; 674 break;
665 675
666 case STDDISPID_XOBJ_ONPROPERTYCHANGE: 676 case STDDISPID_XOBJ_ONPROPERTYCHANGE:
667 return VARIANT_TRUE; 677 break;
668 678
669 case DISPID_READYSTATECHANGE: 679 case DISPID_READYSTATECHANGE:
670 DEBUG_NAVI("Navi::ReadyStateChange") 680 DEBUG_NAVI("Navi::ReadyStateChange");
671 return VARIANT_TRUE; 681 break;
672 682
673 case DISPID_BEFORENAVIGATE: 683 case DISPID_BEFORENAVIGATE:
674 DEBUG_NAVI("Navi::BeforeNavigate") 684 DEBUG_NAVI("Navi::BeforeNavigate");
675 return VARIANT_TRUE; 685 break;
676 case DISPID_COMMANDSTATECHANGE: 686
677 if (m_hPaneWnd == NULL) 687 case DISPID_COMMANDSTATECHANGE:
678 { 688 if (m_hPaneWnd == NULL)
679 CreateStatusBarPane();
680 }
681 else
682 {
683 if (CPluginClient::GetInstance()->GetIEVersion() > 6)
684 { 689 {
685 RECT rect; 690 CreateStatusBarPane();
686 BOOL rectRes = GetClientRect(m_hStatusBarWnd, &rect); 691 }
687 if (rectRes == TRUE) 692 else
693 {
694 if (CPluginClient::GetInstance()->GetIEVersion() > 6)
688 { 695 {
689 MoveWindow(m_hPaneWnd, rect.right - 200, 0, m_nPaneWidth, rect.bottom - rect.top, TRUE); 696 RECT rect;
697 BOOL rectRes = GetClientRect(m_hStatusBarWnd, &rect);
698 if (rectRes == TRUE)
699 {
700 MoveWindow(m_hPaneWnd, rect.right - 200, 0, m_nPaneWidth, rect.botto m - rect.top, TRUE);
701 }
702 }
703 }
704 break;
705
706 case DISPID_STATUSTEXTCHANGE:
707 break;
708
709 case DISPID_BEFORENAVIGATE2:
710 {
711 // #1163 should validate and convert parameters here
712 BeforeNavigate2(pDispParams);
713 }
714 break;
715
716 case DISPID_DOWNLOADBEGIN:
717 {
718 DEBUG_NAVI("Navi::Download Begin")
719 }
720 break;
721
722 case DISPID_DOWNLOADCOMPLETE:
723 {
724 DEBUG_NAVI("Navi::Download Complete");
725 CComQIPtr<IWebBrowser2> browser = GetBrowser();
726 if (browser)
727 {
728 m_tab->OnDownloadComplete(browser);
690 } 729 }
691 } 730 }
692 } 731 break;
693 break;
694 case DISPID_STATUSTEXTCHANGE:
695 break;
696 732
697 case DISPID_BEFORENAVIGATE2: 733 case DISPID_DOCUMENTCOMPLETE:
698 BeforeNavigate2(pDispParams); 734 {
699 break; 735 DEBUG_NAVI("Navi::Document Complete");
700
701 case DISPID_DOWNLOADBEGIN:
702 {
703 DEBUG_NAVI("Navi::Download Begin")
704 }
705 break;
706
707 case DISPID_DOWNLOADCOMPLETE:
708 {
709 DEBUG_NAVI("Navi::Download Complete")
710
711 CComQIPtr<IWebBrowser2> browser = GetBrowser(); 736 CComQIPtr<IWebBrowser2> browser = GetBrowser();
712 if (browser) 737 if (browser && pDispParams->cArgs >= 2 && pDispParams->rgvarg[1].vt == V T_DISPATCH)
713 {
714 m_tab->OnDownloadComplete(browser);
715 }
716 }
717 break;
718
719 case DISPID_DOCUMENTCOMPLETE:
720 {
721 DEBUG_NAVI("Navi::Document Complete")
722
723 CComQIPtr<IWebBrowser2> browser = GetBrowser();
724
725 if (browser && pDispParams->cArgs >= 2 && pDispParams->rgvarg[1].vt == VT_ DISPATCH)
726 {
727 CComQIPtr<IWebBrowser2> pBrowser = pDispParams->rgvarg[1].pdispVal;
728 if (pBrowser)
729 { 738 {
730 CString url; 739 CComQIPtr<IWebBrowser2> pBrowser = pDispParams->rgvarg[1].pdispVal;
731 CComBSTR bstrUrl; 740 if (pBrowser)
732 if (SUCCEEDED(pBrowser->get_LocationURL(&bstrUrl)) && ::SysStringLen(b strUrl) > 0)
733 { 741 {
734 url = bstrUrl; 742 CString url;
735 743 CComBSTR bstrUrl;
736 CPluginClient::UnescapeUrl(url); 744 if (SUCCEEDED(pBrowser->get_LocationURL(&bstrUrl)) && ::SysStringLen (bstrUrl) > 0)
737 745 {
738 m_tab->OnDocumentComplete(browser, url, browser.IsEqualObject(pBrows er)); 746 url = bstrUrl;
747 CPluginClient::UnescapeUrl(url);
748 m_tab->OnDocumentComplete(browser, url, browser.IsEqualObject(pBro wser));
749 }
739 } 750 }
740 } 751 }
741 } 752 }
753 break;
754
755 case DISPID_ONQUIT:
756 case DISPID_QUIT:
757 {
758 Unadvice();
759 }
760 break;
761
762 default:
763 {
764 CString did;
765 did.Format(L"DispId:%u", dispidMember);
766
767 DEBUG_NAVI(L"Navi::Default " + did)
768 }
769 /*
770 * Ordinarily a method not dispatched should return DISP_E_MEMBERNOTFOUND.
771 * As a conservative initial change, we leave it behaving as before,
772 * which is to do nothing and return S_OK.
773 */
774 // do nothing
775 break;
742 } 776 }
743 break;
744
745 case DISPID_ONQUIT:
746 case DISPID_QUIT:
747 {
748 Unadvice();
749 }
750 break;
751
752 default:
753 {
754 CString did;
755 did.Format(L"DispId:%u", dispidMember);
756
757 DEBUG_NAVI(L"Navi::Default " + did)
758 }
759
760 // do nothing
761 break;
762 } 777 }
763 778 catch(...)
764 return VARIANT_TRUE; 779 {
Oleksandr 2014/08/21 14:49:56 Maybe let's log at least something first
Eric 2014/09/29 19:16:44 We could. Got a suggestion? Right now we've got no
Oleksandr 2014/10/02 20:44:16 Yes, I think it would be sufficient. We could in t
Eric 2014/10/02 23:11:02 OK. I just used DEBUG_GENERAL, lacking anything sp
780 return E_FAIL;
781 }
782 return S_OK;
765 } 783 }
766 784
767 bool CPluginClass::InitObject(bool bBHO) 785 bool CPluginClass::InitObject(bool bBHO)
768 { 786 {
769 DEBUG_GENERAL("InitObject"); 787 DEBUG_GENERAL("InitObject");
770 CPluginSettings* settings = CPluginSettings::GetInstance(); 788 CPluginSettings* settings = CPluginSettings::GetInstance();
771 789
772 if (!settings->GetPluginEnabled()) 790 if (!settings->GetPluginEnabled())
773 { 791 {
774 s_mimeFilter->Unregister(); 792 s_mimeFilter->Unregister();
(...skipping 1210 matching lines...) Expand 10 before | Expand all | Expand 10 after
1985 } 2003 }
1986 } 2004 }
1987 } 2005 }
1988 2006
1989 hTabWnd = ::GetWindow(hTabWnd, GW_HWNDNEXT); 2007 hTabWnd = ::GetWindow(hTabWnd, GW_HWNDNEXT);
1990 } 2008 }
1991 2009
1992 return hTabWnd; 2010 return hTabWnd;
1993 2011
1994 } 2012 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld