Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(377)

Side by Side Diff: plugin/linux/main_linux.cc

Issue 4957002: - Check for a NULL PluginObject at all NPAPI entry points. This fixes a crash in Chrome where ... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/o3d/
Patch Set: '' Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « plugin/cross/plugin_logging.h ('k') | plugin/mac/main_mac.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2009, Google Inc. 2 * Copyright 2009, Google Inc.
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are 6 * modification, are permitted provided that the following conditions are
7 * met: 7 * met:
8 * 8 *
9 * * Redistributions of source code must retain the above copyright 9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 15 matching lines...) Expand all
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32 32
33 // This file implements the platform specific parts of the plugin for 33 // This file implements the platform specific parts of the plugin for
34 // the Linux platform. 34 // the Linux platform.
35 35
36 #include "plugin/cross/main.h"
37
36 #include <X11/keysym.h> 38 #include <X11/keysym.h>
37 #include <gdk/gdkx.h> 39 #include <gdk/gdkx.h>
38 #include <gdk/gdkkeysyms.h> 40 #include <gdk/gdkkeysyms.h>
39 #include "base/at_exit.h" 41
40 #include "base/command_line.h"
41 #include "base/file_util.h"
42 #include "base/logging.h" 42 #include "base/logging.h"
43 #include "base/scoped_ptr.h"
44 #include "base/third_party/nspr/prtypes.h" 43 #include "base/third_party/nspr/prtypes.h"
45 #include "o3d/breakpad/linux/breakpad.h" 44 #include "core/cross/event.h"
46 #include "plugin/cross/main.h" 45 #include "core/linux/display_window_linux.h"
47 #include "plugin/cross/out_of_memory.h"
48 #include "plugin/cross/whitelist.h"
49 #include "plugin/linux/envvars.h" 46 #include "plugin/linux/envvars.h"
47 #if !defined(O3D_INTERNAL_PLUGIN)
48 #include "breakpad/linux/breakpad.h"
49 #endif
50 50
51 using glue::_o3d::PluginObject; 51 using glue::_o3d::PluginObject;
52 using glue::StreamManager; 52 using glue::StreamManager;
53 using o3d::DisplayWindowLinux; 53 using o3d::DisplayWindowLinux;
54 using o3d::Event; 54 using o3d::Event;
55 55
56 namespace { 56 namespace {
57 // We would normally make this a stack variable in main(), but in a
58 // plugin, that's not possible, so we make it a global. When the DLL is loaded
59 // this it gets constructed and when it is unlooaded it is destructed. Note
60 // that this cannot be done in NP_Initialize and NP_Shutdown because those
61 // calls do not necessarily signify the DLL being loaded and unloaded. If the
62 // DLL is not unloaded then the values of global variables are preserved.
63 base::AtExitManager g_at_exit_manager;
64 57
65 bool g_xembed_support = false; 58 bool g_xembed_support = false;
66 59
60 #if !defined(O3D_INTERNAL_PLUGIN)
67 o3d::Breakpad g_breakpad; 61 o3d::Breakpad g_breakpad;
62 #endif
68 63
69 #ifdef O3D_PLUGIN_ENV_VARS_FILE 64 #ifdef O3D_PLUGIN_ENV_VARS_FILE
70 static const char *kEnvVarsFilePath = O3D_PLUGIN_ENV_VARS_FILE; 65 static const char kEnvVarsFilePath[] = O3D_PLUGIN_ENV_VARS_FILE;
71 #endif 66 #endif
72 67
73 static void DrawPlugin(PluginObject *obj) { 68 static void DrawPlugin(PluginObject *obj) {
74 // Limit drawing to no more than once every timer tick. 69 // Limit drawing to no more than once every timer tick.
75 if (!obj->draw_) return; 70 if (!obj->draw_) return;
76 // Don't allow re-entrant rendering (can happen in Chrome) 71 // Don't allow re-entrant rendering (can happen in Chrome)
77 if (obj->client()->IsRendering()) return; 72 if (obj->client()->IsRendering()) return;
78 obj->client()->RenderClient(true); 73 obj->client()->RenderClient(true);
79 obj->draw_ = false; 74 obj->draw_ = false;
80 } 75 }
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 widget = obj->gtk_fullscreen_container_; 613 widget = obj->gtk_fullscreen_container_;
619 } else { 614 } else {
620 widget = obj->gtk_container_; 615 widget = obj->gtk_container_;
621 } 616 }
622 gtk_widget_queue_draw(widget); 617 gtk_widget_queue_draw(widget);
623 } 618 }
624 } 619 }
625 return TRUE; 620 return TRUE;
626 } 621 }
627 622
628 NPError InitializePlugin() { 623 } // end anonymous namespace
629 if (!o3d::SetupOutOfMemoryHandler())
630 return NPERR_MODULE_LOAD_FAILED_ERROR;
631 624
625 namespace o3d {
626
627 NPError PlatformPreNPInitialize() {
628 #if !defined(O3D_INTERNAL_PLUGIN)
632 // Setup breakpad 629 // Setup breakpad
633 g_breakpad.Initialize(); 630 g_breakpad.Initialize();
634 g_breakpad.set_version(O3D_PLUGIN_VERSION); 631 g_breakpad.set_version(O3D_PLUGIN_VERSION);
632 #endif
633 return NPERR_NO_ERROR;
634 }
635 635
636 CommandLine::Init(0, NULL); 636 NPError PlatformPostNPInitialize() {
637
638 FilePath log;
639 file_util::GetTempDir(&log);
640 log = log.Append("debug.log");
641
642 InitLogging(log.value().c_str(),
643 logging::LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG,
644 logging::DONT_LOCK_LOG_FILE,
645 logging::APPEND_TO_OLD_LOG_FILE);
646
647 DLOG(INFO) << "NP_Initialize";
648
649 #ifdef O3D_PLUGIN_ENV_VARS_FILE 637 #ifdef O3D_PLUGIN_ENV_VARS_FILE
650 // Before doing anything more, we first load our environment variables file. 638 // Before doing anything more, we first load our environment variables file.
651 // This file is a newline-delimited list of any system-specific environment 639 // This file is a newline-delimited list of any system-specific environment
652 // variables that need to be set in the browser. Since we are a shared library 640 // variables that need to be set in the browser. Since we are a shared library
653 // and not an executable, we can't set them at browser start time, so we 641 // and not an executable, we can't set them at browser start time, so we
654 // instead set them in every process that loads our shared library. It is 642 // instead set them in every process that loads our shared library. It is
655 // important that we do this as early as possible so that any relevant 643 // important that we do this as early as possible so that any relevant
656 // variables are already set when we initialize our shared library 644 // variables are already set when we initialize our shared library
657 // dependencies. 645 // dependencies.
658 o3d::LoadEnvironmentVariablesFile(kEnvVarsFilePath); 646 o3d::LoadEnvironmentVariablesFile(kEnvVarsFilePath);
(...skipping 14 matching lines...) Expand all
673 NPNToolkitType toolkit = static_cast<NPNToolkitType>(0); 661 NPNToolkitType toolkit = static_cast<NPNToolkitType>(0);
674 err = NPN_GetValue(NULL, NPNVToolkit, &toolkit); 662 err = NPN_GetValue(NULL, NPNVToolkit, &toolkit);
675 if (err != NPERR_NO_ERROR || toolkit != NPNVGtk2) 663 if (err != NPERR_NO_ERROR || toolkit != NPNVGtk2)
676 xembed_support = PR_FALSE; 664 xembed_support = PR_FALSE;
677 } 665 }
678 g_xembed_support = xembed_support != PR_FALSE; 666 g_xembed_support = xembed_support != PR_FALSE;
679 667
680 return NPERR_NO_ERROR; 668 return NPERR_NO_ERROR;
681 } 669 }
682 670
683 } // end anonymous namespace 671 NPError PlatformPreNPShutdown() {
684 672 return NPERR_NO_ERROR;
685 #if defined(O3D_INTERNAL_PLUGIN)
686 namespace o3d {
687 #else
688 extern "C" {
689 #endif
690
691 NPError EXPORT_SYMBOL OSCALL NP_Initialize(NPNetscapeFuncs *browserFuncs,
692 NPPluginFuncs *pluginFuncs) {
693 NPError retval = InitializeNPNApi(browserFuncs);
694 if (retval != NPERR_NO_ERROR) return retval;
695 NP_GetEntryPoints(pluginFuncs);
696 return InitializePlugin();
697 } 673 }
698 674
699 NPError EXPORT_SYMBOL OSCALL NP_Shutdown(void) { 675 NPError PlatformPostNPShutdown() {
700 HANDLE_CRASHES; 676 #if !defined(O3D_INTERNAL_PLUGIN)
701 DLOG(INFO) << "NP_Shutdown";
702
703 CommandLine::Reset();
704
705 g_breakpad.Shutdown(); 677 g_breakpad.Shutdown();
678 #endif
706 679
707 return NPERR_NO_ERROR; 680 return NPERR_NO_ERROR;
708 } 681 }
709 682
710 } // namespace o3d / extern "C" 683 NPError PlatformNPPGetValue(PluginObject *obj,
711 684 NPPVariable variable,
712 namespace o3d { 685 void *value) {
713
714 NPError PlatformNPPGetValue(NPP instance, NPPVariable variable, void *value) {
715 switch (variable) { 686 switch (variable) {
716 case NPPVpluginNeedsXEmbed: 687 case NPPVpluginNeedsXEmbed:
717 *static_cast<NPBool *>(value) = g_xembed_support; 688 *static_cast<NPBool *>(value) = g_xembed_support;
718 return NPERR_NO_ERROR; 689 return NPERR_NO_ERROR;
719 default: 690 default:
720 return NPERR_INVALID_PARAM; 691 return NPERR_INVALID_PARAM;
721 } 692 }
722 return NPERR_NO_ERROR; 693 return NPERR_NO_ERROR;
723 } 694 }
724 695
725 NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, 696 NPError PlatformNPPNew(NPP instance, PluginObject *obj) {
726 char *argn[], char *argv[], NPSavedData *saved) {
727 HANDLE_CRASHES;
728
729 if (!IsDomainAuthorized(instance)) {
730 return NPERR_INVALID_URL;
731 }
732
733 PluginObject* pluginObject = glue::_o3d::PluginObject::Create(
734 instance);
735 instance->pdata = pluginObject;
736 glue::_o3d::InitializeGlue(instance);
737 pluginObject->Init(argc, argn, argv);
738
739 // Get the metrics for the system setup
740 GetUserConfigMetrics();
741 return NPERR_NO_ERROR; 697 return NPERR_NO_ERROR;
742 } 698 }
743 699
744 NPError NPP_Destroy(NPP instance, NPSavedData **save) { 700 NPError PlatformNPPDestroy(NPP instance, PluginObject *obj) {
745 HANDLE_CRASHES; 701 // TODO(tschmelcher): Do we really have to do this before the other teardown
746 PluginObject *obj = static_cast<PluginObject*>(instance->pdata); 702 // below? If not then we can factor out the platform-specific TearDown()
747 if (obj) { 703 // calls into NPP_Destroy() in main.cc.
748 obj->TearDown(); 704 obj->TearDown();
749 705
750 if (obj->xt_widget_) { 706 if (obj->xt_widget_) {
751 // NOTE: This crashes. Not sure why, possibly the widget has 707 // NOTE: This crashes. Not sure why, possibly the widget has
752 // already been destroyed, but we haven't received a SetWindow(NULL). 708 // already been destroyed, but we haven't received a SetWindow(NULL).
753 // XtRemoveEventHandler(obj->xt_widget_, ExposureMask, False, 709 // XtRemoveEventHandler(obj->xt_widget_, ExposureMask, False,
754 // LinuxExposeHandler, obj); 710 // LinuxExposeHandler, obj);
755 obj->xt_widget_ = NULL; 711 obj->xt_widget_ = NULL;
756 }
757 if (obj->xt_interval_) {
758 XtRemoveTimeOut(obj->xt_interval_);
759 obj->xt_interval_ = 0;
760 }
761 if (obj->timeout_id_) {
762 g_source_remove(obj->timeout_id_);
763 obj->timeout_id_ = 0;
764 }
765 if (obj->gtk_container_) {
766 gtk_widget_destroy(obj->gtk_container_);
767 obj->gtk_container_ = NULL;
768 }
769 if (obj->gtk_fullscreen_container_) {
770 gtk_widget_destroy(obj->gtk_fullscreen_container_);
771 obj->gtk_fullscreen_container_ = NULL;
772 }
773 if (obj->gdk_display_) {
774 gdk_display_close(obj->gdk_display_);
775 obj->gdk_display_ = NULL;
776 }
777 obj->gtk_event_source_ = NULL;
778 obj->event_handler_id_ = 0;
779 obj->window_ = 0;
780 obj->drawable_ = 0;
781
782 NPN_ReleaseObject(obj);
783 instance->pdata = NULL;
784 } 712 }
713 if (obj->xt_interval_) {
714 XtRemoveTimeOut(obj->xt_interval_);
715 obj->xt_interval_ = 0;
716 }
717 if (obj->timeout_id_) {
718 g_source_remove(obj->timeout_id_);
719 obj->timeout_id_ = 0;
720 }
721 if (obj->gtk_container_) {
722 gtk_widget_destroy(obj->gtk_container_);
723 obj->gtk_container_ = NULL;
724 }
725 if (obj->gtk_fullscreen_container_) {
726 gtk_widget_destroy(obj->gtk_fullscreen_container_);
727 obj->gtk_fullscreen_container_ = NULL;
728 }
729 if (obj->gdk_display_) {
730 gdk_display_close(obj->gdk_display_);
731 obj->gdk_display_ = NULL;
732 }
733 obj->gtk_event_source_ = NULL;
734 obj->event_handler_id_ = 0;
735 obj->window_ = 0;
736 obj->drawable_ = 0;
785 return NPERR_NO_ERROR; 737 return NPERR_NO_ERROR;
786 } 738 }
787 739
788 NPError NPP_SetWindow(NPP instance, NPWindow *window) { 740 NPError PlatformNPPSetWindow(NPP instance,
789 HANDLE_CRASHES; 741 PluginObject *obj,
790 PluginObject *obj = static_cast<PluginObject*>(instance->pdata); 742 NPWindow *window) {
791
792 NPSetWindowCallbackStruct *cb_struct = 743 NPSetWindowCallbackStruct *cb_struct =
793 static_cast<NPSetWindowCallbackStruct *>(window->ws_info); 744 static_cast<NPSetWindowCallbackStruct *>(window->ws_info);
794 Window xwindow = reinterpret_cast<Window>(window->window); 745 Window xwindow = reinterpret_cast<Window>(window->window);
795 if (xwindow != obj->window_) { 746 if (xwindow != obj->window_) {
796 Display *display = cb_struct->display; 747 Display *display = cb_struct->display;
797 Window drawable = xwindow; 748 Window drawable = xwindow;
798 if (g_xembed_support) { 749 if (g_xembed_support) {
799 // We asked for a XEmbed plugin, the xwindow is a GtkSocket, we create 750 // We asked for a XEmbed plugin, the xwindow is a GtkSocket, we create
800 // a GtkPlug to go into it. 751 // a GtkPlug to go into it.
801 obj->gdk_display_ = gdk_display_open(XDisplayString(display)); 752 obj->gdk_display_ = gdk_display_open(XDisplayString(display));
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
847 obj->client()->Init(); 798 obj->client()->Init();
848 obj->SetDisplay(display); 799 obj->SetDisplay(display);
849 obj->window_ = xwindow; 800 obj->window_ = xwindow;
850 obj->drawable_ = drawable; 801 obj->drawable_ = drawable;
851 } 802 }
852 obj->Resize(window->width, window->height); 803 obj->Resize(window->width, window->height);
853 804
854 return NPERR_NO_ERROR; 805 return NPERR_NO_ERROR;
855 } 806 }
856 807
857 // Called when the browser has finished attempting to stream data to 808 void PlatformNPPStreamAsFile(StreamManager *stream_manager,
858 // a file as requested. If fname == NULL the attempt was not successful. 809 NPStream *stream,
859 void NPP_StreamAsFile(NPP instance, NPStream *stream, const char *fname) { 810 const char *fname) {
860 HANDLE_CRASHES;
861 PluginObject *obj = static_cast<PluginObject*>(instance->pdata);
862 StreamManager *stream_manager = obj->stream_manager();
863
864 stream_manager->SetStreamFile(stream, fname); 811 stream_manager->SetStreamFile(stream, fname);
865 } 812 }
866 813
867 int16 NPP_HandleEvent(NPP instance, void *event) { 814 int16 PlatformNPPHandleEvent(NPP instance, PluginObject *obj, void *event) {
868 HANDLE_CRASHES;
869 return 0; 815 return 0;
870 } 816 }
817
871 } // namespace o3d 818 } // namespace o3d
872 819
820 // TODO(tschmelcher): This stuff does not belong in this file.
873 namespace glue { 821 namespace glue {
874 namespace _o3d { 822 namespace _o3d {
875 823
876 void PluginObject::SetGtkEventSource(GtkWidget *widget) { 824 void PluginObject::SetGtkEventSource(GtkWidget *widget) {
877 if (gtk_event_source_) { 825 if (gtk_event_source_) {
878 g_signal_handler_disconnect(G_OBJECT(gtk_event_source_), 826 g_signal_handler_disconnect(G_OBJECT(gtk_event_source_),
879 event_handler_id_); 827 event_handler_id_);
880 } 828 }
881 gtk_event_source_ = widget; 829 gtk_event_source_ = widget;
882 if (gtk_event_source_) { 830 if (gtk_event_source_) {
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1008 client()->SendResizeEvent(renderer()->width(), renderer()->height(), 956 client()->SendResizeEvent(renderer()->width(), renderer()->height(),
1009 false); 957 false);
1010 SetGtkEventSource(gtk_container_); 958 SetGtkEventSource(gtk_container_);
1011 gtk_widget_destroy(gtk_fullscreen_container_); 959 gtk_widget_destroy(gtk_fullscreen_container_);
1012 gtk_fullscreen_container_ = NULL; 960 gtk_fullscreen_container_ = NULL;
1013 fullscreen_window_ = 0; 961 fullscreen_window_ = 0;
1014 fullscreen_ = false; 962 fullscreen_ = false;
1015 } 963 }
1016 } // namespace _o3d 964 } // namespace _o3d
1017 } // namespace glue 965 } // namespace glue
OLDNEW
« no previous file with comments | « plugin/cross/plugin_logging.h ('k') | plugin/mac/main_mac.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698