From 9be46b97cfc0b7bbc5c9730145829859054fa249 Mon Sep 17 00:00:00 2001 From: Aaron Klotz Date: Wed, 8 Apr 2015 11:31:18 -0600 Subject: [PATCH] Bug 1152395: Ensure that NP_Shutdown respects async plugin init; r=jimm --HG-- extra : rebase_source : 2fc1fda02d611303d18eb24a438ed2ac223a52f7 --- dom/plugins/ipc/PluginModuleParent.cpp | 47 +++++++++++++++++++++++++- dom/plugins/ipc/PluginModuleParent.h | 3 ++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index d4ebfec0f47c..3808276999ed 100755 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -618,6 +618,7 @@ PluginModuleParent::PluginModuleParent(bool aIsChrome) , mIsFlashPlugin(false) , mIsStartingAsync(false) , mNPInitialized(false) + , mIsNPShutdownPending(false) , mAsyncNewRv(NS_ERROR_NOT_INITIALIZED) { #if defined(XP_WIN) || defined(XP_MACOSX) || defined(MOZ_WIDGET_GTK) @@ -2275,6 +2276,13 @@ PluginModuleChromeParent::RecvNP_InitializeResult(const NPError& aError) void PluginModuleParent::InitAsyncSurrogates() { + if (MaybeRunDeferredShutdown()) { + // We've shut down, so the surrogates are no longer valid. Clear + // mSurrogateInstances to ensure that these aren't used. + mSurrogateInstances.Clear(); + return; + } + uint32_t len = mSurrogateInstances.Length(); for (uint32_t i = 0; i < len; ++i) { NPError err; @@ -2294,6 +2302,21 @@ PluginModuleParent::RemovePendingSurrogate( return mSurrogateInstances.RemoveElement(aSurrogate); } +bool +PluginModuleParent::MaybeRunDeferredShutdown() +{ + if (!mIsStartingAsync || !mIsNPShutdownPending) { + return false; + } + MOZ_ASSERT(!mShutdown); + NPError error; + if (!DoShutdown(&error)) { + return false; + } + mIsNPShutdownPending = false; + return true; +} + nsresult PluginModuleParent::NP_Shutdown(NPError* error) { @@ -2304,6 +2327,24 @@ PluginModuleParent::NP_Shutdown(NPError* error) return NS_ERROR_FAILURE; } + /* If we're still running an async NP_Initialize then we need to defer + shutdown until we've received the result of the NP_Initialize call. */ + if (mIsStartingAsync && !mNPInitialized) { + mIsNPShutdownPending = true; + *error = NPERR_NO_ERROR; + return NS_OK; + } + + if (!DoShutdown(error)) { + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + +bool +PluginModuleParent::DoShutdown(NPError* error) +{ bool ok = true; if (IsChrome()) { ok = CallNP_Shutdown(error); @@ -2315,7 +2356,11 @@ PluginModuleParent::NP_Shutdown(NPError* error) // CallNP_Shutdown() message Close(); - return ok ? NS_OK : NS_ERROR_FAILURE; + mShutdown = ok; + if (!ok) { + *error = NPERR_GENERIC_ERROR; + } + return ok; } nsresult diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h index a545a432e1c6..3f5a7077f971 100644 --- a/dom/plugins/ipc/PluginModuleParent.h +++ b/dom/plugins/ipc/PluginModuleParent.h @@ -270,6 +270,8 @@ protected: void NotifyFlashHang(); void NotifyPluginCrashed(); void OnInitFailure(); + bool MaybeRunDeferredShutdown(); + bool DoShutdown(NPError* error); bool GetSetting(NPNVariable aVariable); void GetSettings(PluginSettings* aSettings); @@ -305,6 +307,7 @@ protected: bool mIsStartingAsync; bool mNPInitialized; + bool mIsNPShutdownPending; nsTArray> mSurrogateInstances; nsresult mAsyncNewRv; uint32_t mRunID;