From 4f5d9236230998a12657c404597dbd1a25d8d90d Mon Sep 17 00:00:00 2001 From: Josh Aas Date: Fri, 9 Apr 2010 11:08:55 -0400 Subject: [PATCH] Back out patch from bug 554524 due to crashes. --- .../plugin/base/src/nsNPAPIPluginInstance.cpp | 92 ++++++++++++++++--- .../plugin/base/src/nsNPAPIPluginInstance.h | 12 ++- .../base/src/nsNPAPIPluginStreamListener.h | 2 +- 3 files changed, 89 insertions(+), 17 deletions(-) diff --git a/modules/plugin/base/src/nsNPAPIPluginInstance.cpp b/modules/plugin/base/src/nsNPAPIPluginInstance.cpp index 8dd5bc43248..ed110a8ae1e 100644 --- a/modules/plugin/base/src/nsNPAPIPluginInstance.cpp +++ b/modules/plugin/base/src/nsNPAPIPluginInstance.cpp @@ -204,10 +204,30 @@ nsNPAPIPluginStreamListener::nsNPAPIPluginStreamListener(nsNPAPIPluginInstance* mResponseHeaderBuf(nsnull) { memset(&mNPStream, 0, sizeof(mNPStream)); + + NS_IF_ADDREF(mInst); } -nsNPAPIPluginStreamListener::~nsNPAPIPluginStreamListener() +nsNPAPIPluginStreamListener::~nsNPAPIPluginStreamListener(void) { + // remove itself from the instance stream list + nsNPAPIPluginInstance *inst = mInst; + if (inst) { + nsInstanceStream * prev = nsnull; + for (nsInstanceStream *is = inst->mStreams; is != nsnull; is = is->mNext) { + if (is->mPluginStreamListener == this) { + if (!prev) + inst->mStreams = is->mNext; + else + prev->mNext = is->mNext; + + delete is; + break; + } + prev = is; + } + } + // For those cases when NewStream is never called, we still may need // to fire a notification callback. Return network error as fallback // reason because for other cases, notify should have already been @@ -220,6 +240,8 @@ nsNPAPIPluginStreamListener::~nsNPAPIPluginStreamListener() mStreamBuffer=nsnull; } + NS_IF_RELEASE(inst); + if (mNotifyURL) PL_strfree(mNotifyURL); @@ -243,7 +265,7 @@ nsresult nsNPAPIPluginStreamListener::CleanUpStream(NPReason reason) if (NP_SEEK == mStreamType) NS_RELEASE_THIS(); - if (!mInst->CanFireNotifications()) + if (!mInst || !mInst->CanFireNotifications()) return rv; mStreamInfo = NULL; @@ -284,7 +306,7 @@ nsresult nsNPAPIPluginStreamListener::CleanUpStream(NPReason reason) void nsNPAPIPluginStreamListener::CallURLNotify(NPReason reason) { - if (!mCallNotify || !mInst->CanFireNotifications()) + if (!mCallNotify || !mInst || !mInst->CanFireNotifications()) return; PluginDestructionGuard guard(mInst); @@ -297,6 +319,7 @@ void nsNPAPIPluginStreamListener::CallURLNotify(NPReason reason) return; if (callbacks->urlnotify) { + NPP npp; mInst->GetNPP(&npp); @@ -311,6 +334,9 @@ void nsNPAPIPluginStreamListener::CallURLNotify(NPReason reason) NS_IMETHODIMP nsNPAPIPluginStreamListener::OnStartBinding(nsIPluginStreamInfo* pluginInfo) { + if (!mInst) + return NS_ERROR_FAILURE; + PluginDestructionGuard guard(mInst); NPP npp; @@ -447,8 +473,8 @@ nsNPAPIPluginStreamListener::StopDataPump() PRBool nsNPAPIPluginStreamListener::PluginInitJSLoadInProgress() { - for (unsigned int i = 0; i < mInst->mStreams.Length(); i++) { - if (mInst->mStreams[i]->mIsPluginInitJSStream) { + for (nsInstanceStream *is = mInst->mStreams; is; is = is->mNext) { + if (is->mPluginStreamListener->mIsPluginInitJSStream) { return PR_TRUE; } } @@ -468,7 +494,7 @@ nsNPAPIPluginStreamListener::OnDataAvailable(nsIPluginStreamInfo* pluginInfo, nsIInputStream* input, PRUint32 length) { - if (!mInst->CanFireNotifications()) + if (!mInst || !mInst->CanFireNotifications()) return NS_ERROR_FAILURE; PluginDestructionGuard guard(mInst); @@ -733,7 +759,7 @@ NS_IMETHODIMP nsNPAPIPluginStreamListener::OnFileAvailable(nsIPluginStreamInfo* pluginInfo, const char* fileName) { - if (!mInst->CanFireNotifications()) + if (!mInst || !mInst->CanFireNotifications()) return NS_ERROR_FAILURE; PluginDestructionGuard guard(mInst); @@ -776,7 +802,7 @@ nsNPAPIPluginStreamListener::OnStopBinding(nsIPluginStreamInfo* pluginInfo, } } - if (!mInst->CanFireNotifications()) + if (!mInst || !mInst->CanFireNotifications()) return NS_ERROR_FAILURE; // check if the stream is of seekable type and later its destruction @@ -847,6 +873,16 @@ nsNPAPIPluginStreamListener::NewResponseHeader(const char* headerName, return NS_OK; } +nsInstanceStream::nsInstanceStream() +{ + mNext = nsnull; + mPluginStreamListener = nsnull; +} + +nsInstanceStream::~nsInstanceStream() +{ +} + NS_IMPL_ISUPPORTS1(nsNPAPIPluginInstance, nsIPluginInstance) nsNPAPIPluginInstance::nsNPAPIPluginInstance(NPPluginFuncs* callbacks, @@ -882,10 +918,17 @@ nsNPAPIPluginInstance::nsNPAPIPluginInstance(NPPluginFuncs* callbacks, PLUGIN_LOG(PLUGIN_LOG_BASIC, ("nsNPAPIPluginInstance ctor: this=%p\n",this)); } -nsNPAPIPluginInstance::~nsNPAPIPluginInstance() +nsNPAPIPluginInstance::~nsNPAPIPluginInstance(void) { PLUGIN_LOG(PLUGIN_LOG_BASIC, ("nsNPAPIPluginInstance dtor: this=%p\n",this)); + // clean the stream list if any + for (nsInstanceStream *is = mStreams; is != nsnull;) { + nsInstanceStream * next = is->mNext; + delete is; + is = next; + } + if (mMIMEType) { PR_Free((void *)mMIMEType); mMIMEType = nsnull; @@ -961,10 +1004,19 @@ NS_IMETHODIMP nsNPAPIPluginInstance::Stop() OnPluginDestroy(&mNPP); // clean up open streams - for (unsigned int i = 0; i < mStreams.Length(); i++) { - mStreams[i]->CleanUpStream(NPRES_USER_BREAK); + for (nsInstanceStream *is = mStreams; is != nsnull;) { + nsRefPtr listener = is->mPluginStreamListener; + + nsInstanceStream *next = is->mNext; + delete is; + is = next; + mStreams = is; + + // Clean up our stream after removing it from the list because + // it may be released and destroyed at this point. + if (listener) + listener->CleanUpStream(NPRES_USER_BREAK); } - mStreams.Clear(); NPError error = NPERR_GENERIC_ERROR; if (mCallbacks->destroy) { @@ -1244,11 +1296,23 @@ nsresult nsNPAPIPluginInstance::NewNotifyStream(nsIPluginStreamListener** listen nsNPAPIPluginStreamListener* stream = new nsNPAPIPluginStreamListener(this, notifyData, aURL); NS_ENSURE_TRUE(stream, NS_ERROR_OUT_OF_MEMORY); - mStreams.AppendElement(stream); + // add it to the list + nsInstanceStream * is = new nsInstanceStream(); + NS_ENSURE_TRUE(is, NS_ERROR_OUT_OF_MEMORY); + is->mNext = mStreams; + is->mPluginStreamListener = stream; + mStreams = is; stream->SetCallNotify(aCallNotify); // set flag in stream to call URLNotify - return stream->QueryInterface(kIPluginStreamListenerIID, (void**)listener); + NS_ADDREF(stream); // Stabilize + + nsresult res = stream->QueryInterface(kIPluginStreamListenerIID, (void**)listener); + + // Destabilize and avoid leaks. Avoid calling delete + NS_RELEASE(stream); + + return res; } NS_IMETHODIMP nsNPAPIPluginInstance::Print(NPPrint* platformPrint) diff --git a/modules/plugin/base/src/nsNPAPIPluginInstance.h b/modules/plugin/base/src/nsNPAPIPluginInstance.h index 05eabba00a7..be2489f333d 100644 --- a/modules/plugin/base/src/nsNPAPIPluginInstance.h +++ b/modules/plugin/base/src/nsNPAPIPluginInstance.h @@ -41,7 +41,6 @@ #define nsNPAPIPluginInstance_h_ #include "nsCOMPtr.h" -#include "nsAutoPtr.h" #include "nsTArray.h" #include "nsIPlugin.h" #include "nsIPluginInstance.h" @@ -57,6 +56,15 @@ class nsNPAPIPluginStreamListener; class nsPIDOMWindow; +struct nsInstanceStream +{ + nsInstanceStream *mNext; + nsNPAPIPluginStreamListener *mPluginStreamListener; + + nsInstanceStream(); + ~nsInstanceStream(); +}; + class nsNPAPITimer { public: @@ -172,7 +180,7 @@ public: // True while creating the plugin, or calling NPP_SetWindow() on it. PRPackedBool mInPluginInitCall; PluginLibrary* mLibrary; - nsTArray< nsRefPtr > mStreams; + nsInstanceStream *mStreams; private: nsTArray mPopupStates; diff --git a/modules/plugin/base/src/nsNPAPIPluginStreamListener.h b/modules/plugin/base/src/nsNPAPIPluginStreamListener.h index 337f82d59fc..5ad72a99f31 100644 --- a/modules/plugin/base/src/nsNPAPIPluginStreamListener.h +++ b/modules/plugin/base/src/nsNPAPIPluginStreamListener.h @@ -85,7 +85,7 @@ protected: void* mNotifyData; char* mStreamBuffer; char* mNotifyURL; - nsNPAPIPluginInstance* mInst; // weak, must always be valid + nsNPAPIPluginInstance* mInst; NPStream mNPStream; PRUint32 mStreamBufferSize; PRInt32 mStreamBufferByteCount;