diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-18 20:51:18 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-18 20:51:18 +0000 |
commit | 3502a996955e749fa48f202ee27a63fbda528c03 (patch) | |
tree | 68f02d46f25c94cc4efee9116c84c69e5da59a57 /ppapi/proxy | |
parent | 88ddb358c1ccf049220487925ea9831e5f8ea452 (diff) | |
download | chromium_src-3502a996955e749fa48f202ee27a63fbda528c03.zip chromium_src-3502a996955e749fa48f202ee27a63fbda528c03.tar.gz chromium_src-3502a996955e749fa48f202ee27a63fbda528c03.tar.bz2 |
Keep the module in scope when executing scripts. This prevents a crash when the
script deletes the plugin object synchronously. This in turn deletes the
dispatcher which will make the code returning the out param and exception to
the plugin crash.
To prevent the crash, this patch adds a way for the proxy to manipulate the
refcount of the plugin object so that it's still alive when as long as the
scripting message is being processed.
A manual test is included. This is not automatically run now. I tried to fit it
into the current test infrastructure and found it very challenging, We need to
revisit this to allow custom tests to more easily be written.
TEST=manual with included plugin and html
BUG=none
Review URL: http://codereview.chromium.org/6881012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@81993 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/proxy')
-rw-r--r-- | ppapi/proxy/host_dispatcher.cc | 12 | ||||
-rw-r--r-- | ppapi/proxy/host_dispatcher.h | 17 | ||||
-rw-r--r-- | ppapi/proxy/ppb_instance_proxy.cc | 6 | ||||
-rw-r--r-- | ppapi/proxy/ppb_var_deprecated_proxy.cc | 7 |
4 files changed, 42 insertions, 0 deletions
diff --git a/ppapi/proxy/host_dispatcher.cc b/ppapi/proxy/host_dispatcher.cc index 25e06fb..cba66de 100644 --- a/ppapi/proxy/host_dispatcher.cc +++ b/ppapi/proxy/host_dispatcher.cc @@ -240,6 +240,18 @@ InterfaceProxy* HostDispatcher::CreatePPBInterfaceProxy( return proxy; } +// ScopedModuleReference ------------------------------------------------------- + +ScopedModuleReference::ScopedModuleReference(Dispatcher* dispatcher) { + DCHECK(!dispatcher->IsPlugin()); + dispatcher_ = static_cast<HostDispatcher*>(dispatcher); + dispatcher_->ppb_proxy()->AddRefModule(dispatcher_->pp_module()); +} + +ScopedModuleReference::~ScopedModuleReference() { + dispatcher_->ppb_proxy()->ReleaseModule(dispatcher_->pp_module()); +} + } // namespace proxy } // namespace pp diff --git a/ppapi/proxy/host_dispatcher.h b/ppapi/proxy/host_dispatcher.h index ea676d1..2391308 100644 --- a/ppapi/proxy/host_dispatcher.h +++ b/ppapi/proxy/host_dispatcher.h @@ -128,6 +128,23 @@ class HostDispatcher : public Dispatcher { DISALLOW_COPY_AND_ASSIGN(HostDispatcher); }; +// Create this object on the stack to prevent the module (and hence the +// dispatcher) from being deleted out from under you. This is necessary when +// calling some scripting functions that may delete the plugin. +// +// This may only be called in the host. The parameter is a plain Dispatcher +// since that's what most callers have. +class ScopedModuleReference { + public: + ScopedModuleReference(Dispatcher* dispatcher); + ~ScopedModuleReference(); + + private: + HostDispatcher* dispatcher_; + + DISALLOW_COPY_AND_ASSIGN(ScopedModuleReference); +}; + } // namespace proxy } // namespace pp diff --git a/ppapi/proxy/ppb_instance_proxy.cc b/ppapi/proxy/ppb_instance_proxy.cc index 4d6f5f3..b2d6291 100644 --- a/ppapi/proxy/ppb_instance_proxy.cc +++ b/ppapi/proxy/ppb_instance_proxy.cc @@ -120,6 +120,12 @@ const InterfaceProxy::Info* PPB_Instance_Proxy::GetInfo() { } bool PPB_Instance_Proxy::OnMessageReceived(const IPC::Message& msg) { + // Prevent the dispatcher from going away during a call to ExecuteScript. + // This must happen OUTSIDE of ExecuteScript since the SerializedVars use + // the dispatcher upon return of the function (converting the + // SerializedVarReturnValue/OutParam to a SerializedVar in the destructor). + ScopedModuleReference death_grip(dispatcher()); + bool handled = true; IPC_BEGIN_MESSAGE_MAP(PPB_Instance_Proxy, msg) IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetWindowObject, diff --git a/ppapi/proxy/ppb_var_deprecated_proxy.cc b/ppapi/proxy/ppb_var_deprecated_proxy.cc index 9571689..aca0a9e 100644 --- a/ppapi/proxy/ppb_var_deprecated_proxy.cc +++ b/ppapi/proxy/ppb_var_deprecated_proxy.cc @@ -315,6 +315,13 @@ const InterfaceProxy::Info* PPB_Var_Deprecated_Proxy::GetInfo() { } bool PPB_Var_Deprecated_Proxy::OnMessageReceived(const IPC::Message& msg) { + // Prevent the dispatcher from going away during a call to Call or other + // function that could mutate the DOM. This must happen OUTSIDE of + // the message handlers since the SerializedVars use the dispatcher upon + // return of the function (converting the SerializedVarReturnValue/OutParam + // to a SerializedVar in the destructor). + ScopedModuleReference death_grip(dispatcher()); + bool handled = true; IPC_BEGIN_MESSAGE_MAP(PPB_Var_Deprecated_Proxy, msg) IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_HasProperty, |