From ba687619309d26f103ebf117fbafcf061d448692 Mon Sep 17 00:00:00 2001 From: "serge%netscape.com" Date: Sun, 26 May 2002 22:52:19 +0000 Subject: [PATCH] fix for #145377, crash after closing acrobat plugin, r=av, sr=darin git-svn-id: svn://10.0.0.236/trunk@122189 18797224-902f-48f8-a5cc-f745e15eee43 --- .../plugin/base/src/nsPluginHostImpl.cpp | 134 ++++++++++++------ 1 file changed, 90 insertions(+), 44 deletions(-) diff --git a/mozilla/modules/plugin/base/src/nsPluginHostImpl.cpp b/mozilla/modules/plugin/base/src/nsPluginHostImpl.cpp index f1d2ad4ca3f..3085faf2ae2 100644 --- a/mozilla/modules/plugin/base/src/nsPluginHostImpl.cpp +++ b/mozilla/modules/plugin/base/src/nsPluginHostImpl.cpp @@ -150,6 +150,7 @@ #include "imgILoader.h" #include "nsDefaultPlugin.h" +#include "nsWeakReference.h" #ifdef XP_UNIX #if defined(MOZ_WIDGET_GTK) @@ -1207,7 +1208,8 @@ private: class nsPluginStreamListenerPeer : public nsIStreamListener, public nsIProgressEventSink, - public nsIHttpHeaderVisitor + public nsIHttpHeaderVisitor, + public nsSupportsWeakReference { public: nsPluginStreamListenerPeer(); @@ -1238,8 +1240,7 @@ public: nsresult SetLocalFile(nsIFile* aFile); - nsresult ServeStreamAsFile(nsIRequest *request, nsISupports *ctxt, - nsresult status); + nsresult ServeStreamAsFile(nsIRequest *request, nsISupports *ctxt); private: nsresult SetUpCache(nsIURI* aURL); // todo: see about removing this... @@ -1285,7 +1286,7 @@ public: //////////////////////////////////////////////////////////////////////// class nsPluginByteRangeStreamListener : public nsIStreamListener { public: - nsPluginByteRangeStreamListener(nsPluginStreamListenerPeer* aPluginStreamListenerPeer); + nsPluginByteRangeStreamListener(nsIWeakReference* aWeakPtr); virtual ~nsPluginByteRangeStreamListener(); // nsISupports @@ -1299,7 +1300,8 @@ public: private: nsCOMPtr mStreamConverter; - nsPluginStreamListenerPeer* mFinalPluginStreamListener; + nsWeakPtr mWeakPtrPluginStreamListenerPeer; + PRBool mRemoveMagicNumber; }; //////////////////////////////////////////////////////////////////////// @@ -1463,59 +1465,70 @@ nsPluginStreamInfo::RequestRead(nsByteRange* rangeList) { nsCAutoString rangeString; PRInt32 numRequests; + + //first of all lets see if mPluginStreamListenerPeer is still alive + nsCOMPtr suppWeakRef( + do_QueryInterface((nsISupportsWeakReference *)(mPluginStreamListenerPeer))); + if (!suppWeakRef) + return NS_ERROR_FAILURE; + + nsCOMPtr pWeakRefPluginStreamListenerPeer = + getter_AddRefs(NS_GetWeakReference(suppWeakRef)); + if (!pWeakRefPluginStreamListenerPeer) + return NS_ERROR_FAILURE; MakeByteRangeString(rangeList, rangeString, &numRequests); if(numRequests == 0) return NS_ERROR_FAILURE; - + nsresult rv = NS_OK; nsCOMPtr url; - + rv = NS_NewURI(getter_AddRefs(url), nsDependentCString(mURL)); - + nsCOMPtr channel; rv = NS_NewChannel(getter_AddRefs(channel), url, nsnull, nsnull, nsnull); if (NS_FAILED(rv)) return rv; - + nsCOMPtr httpChannel(do_QueryInterface(channel)); if(!httpChannel) return NS_ERROR_FAILURE; - - + httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Range"), rangeString); - mPluginStreamListenerPeer->mAbort = PR_TRUE; // instruct old stream listener to cancel - // the request on the next ODA. + // the request on the next ODA. nsCOMPtr converter; if (numRequests == 1) { - converter = mPluginStreamListenerPeer; - + converter = mPluginStreamListenerPeer; + // set current stream offset equal to the first offset in the range list // it will work for single byte range request // for multy range we'll reset it in ODA SetStreamOffset(rangeList->offset); } else { nsPluginByteRangeStreamListener *brrListener = - new nsPluginByteRangeStreamListener(mPluginStreamListenerPeer); + new nsPluginByteRangeStreamListener(pWeakRefPluginStreamListenerPeer); if (brrListener) converter = brrListener; else return NS_ERROR_OUT_OF_MEMORY; } - + mPluginStreamListenerPeer->mPendingRequests += numRequests; - - nsCOMPtr container = do_CreateInstance(NS_SUPPORTS_PRUINT32_CONTRACTID, &rv); - if (NS_FAILED(rv)) return rv; - rv = container->SetData(MAGIC_REQUEST_CONTEXT); - if (NS_FAILED(rv)) return rv; - - return channel->AsyncOpen(converter, container); + + nsCOMPtr container = do_CreateInstance(NS_SUPPORTS_PRUINT32_CONTRACTID, &rv); + if (NS_FAILED(rv)) + return rv; + rv = container->SetData(MAGIC_REQUEST_CONTEXT); + if (NS_FAILED(rv)) + return rv; + + return channel->AsyncOpen(converter, container); } NS_IMETHODIMP @@ -1767,10 +1780,11 @@ nsPluginStreamListenerPeer::~nsPluginStreamListenerPeer() //////////////////////////////////////////////////////////////////////// -NS_IMPL_ISUPPORTS3(nsPluginStreamListenerPeer, +NS_IMPL_ISUPPORTS4(nsPluginStreamListenerPeer, nsIStreamListener, nsIRequestObserver, - nsIHttpHeaderVisitor) + nsIHttpHeaderVisitor, + nsISupportsWeakReference) //////////////////////////////////////////////////////////////////////// @@ -6576,8 +6590,7 @@ nsPluginHostImpl::ScanForRealInComponentsFolder(nsIComponentManager * aCompManag //////////////////////////////////////////////////////////////////////////////////// nsresult nsPluginStreamListenerPeer::ServeStreamAsFile(nsIRequest *request, - nsISupports* aContext, - nsresult aStatus) + nsISupports* aContext) { if (!mInstance) return NS_ERROR_FAILURE; @@ -6621,22 +6634,25 @@ nsresult nsPluginStreamListenerPeer::ServeStreamAsFile(nsIRequest *request, } #endif + // unset mPendingRequests + mPendingRequests = 0; + return NS_OK; } ////////////////////////////////////////////////////////////////////// NS_IMPL_ISUPPORTS1(nsPluginByteRangeStreamListener, nsIStreamListener) - -nsPluginByteRangeStreamListener::nsPluginByteRangeStreamListener(nsPluginStreamListenerPeer* aPluginStreamListenerPeer) +nsPluginByteRangeStreamListener::nsPluginByteRangeStreamListener(nsIWeakReference* aWeakPtr) { NS_INIT_REFCNT(); - // don't addref - mFinalPluginStreamListener = aPluginStreamListenerPeer; + mWeakPtrPluginStreamListenerPeer = aWeakPtr; + mRemoveMagicNumber = PR_FALSE; } nsPluginByteRangeStreamListener::~nsPluginByteRangeStreamListener() { mStreamConverter = 0; + mWeakPtrPluginStreamListenerPeer = 0; } NS_IMETHODIMP @@ -6644,11 +6660,15 @@ nsPluginByteRangeStreamListener::OnStartRequest(nsIRequest *request, nsISupports { nsresult rv; + nsCOMPtr finalStreamListener = do_QueryReferent(mWeakPtrPluginStreamListenerPeer); + if (!finalStreamListener) + return NS_ERROR_FAILURE; + nsCOMPtr serv = do_GetService(kStreamConverterServiceCID, &rv); if (NS_SUCCEEDED(rv)) { rv = serv->AsyncConvertData(NS_LITERAL_STRING(MULTIPART_BYTERANGES).get(), NS_LITERAL_STRING("*/*").get(), - mFinalPluginStreamListener, + finalStreamListener, nsnull, getter_AddRefs(mStreamConverter)); if (NS_SUCCEEDED(rv)) { @@ -6656,14 +6676,29 @@ nsPluginByteRangeStreamListener::OnStartRequest(nsIRequest *request, nsISupports if (NS_SUCCEEDED(rv)) return rv; } - mStreamConverter = 0; + } + mStreamConverter = 0; + + nsCOMPtr httpChannel(do_QueryInterface(request)); + if (!httpChannel) { + return NS_ERROR_FAILURE; + } + + PRUint32 responseCode = 0; + rv = httpChannel->GetResponseStatus(&responseCode); + if (NS_FAILED(rv) || responseCode != 200) { + return NS_ERROR_FAILURE; } // if server cannot continue with byte range (206 status) and sending us whole object (200 status) // reset this seekable stream & try serve it to plugin instance as a file - rv = mFinalPluginStreamListener->ServeStreamAsFile(request, ctxt, rv); - // always use mFinalPluginStreamListener - mStreamConverter = mFinalPluginStreamListener; + mStreamConverter = finalStreamListener; + mRemoveMagicNumber = PR_TRUE; + + //get nsPluginStreamListenerPeer* ptr from finalStreamListener + nsPluginStreamListenerPeer *pslp = NS_REINTERPRET_CAST(nsPluginStreamListenerPeer*, + *(NS_REINTERPRET_CAST(void**, &finalStreamListener))); + rv = pslp->ServeStreamAsFile(request, ctxt); return rv; } @@ -6671,23 +6706,27 @@ NS_IMETHODIMP nsPluginByteRangeStreamListener::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult status) { - if (mStreamConverter == mFinalPluginStreamListener) { + if (!mStreamConverter) + return NS_ERROR_FAILURE; + + nsCOMPtr finalStreamListener = do_QueryReferent(mWeakPtrPluginStreamListenerPeer); + if (!finalStreamListener) + return NS_ERROR_FAILURE; + + if (mRemoveMagicNumber) { // remove magic number from container nsCOMPtr container = do_QueryInterface(ctxt); if (container) { PRUint32 magicNumber = 0; container->GetData(&magicNumber); if (magicNumber == MAGIC_REQUEST_CONTEXT) { - // to allow properly finish mFinalPluginStreamListener->OnStopRequest() + // to allow properly finish nsPluginStreamListenerPeer->OnStopRequest() // set it to something that is not the magic number. container->SetData(0); - // also unset mPendingRequests - mFinalPluginStreamListener->mPendingRequests = 0; - - return mFinalPluginStreamListener->OnStopRequest(request, ctxt, status); } + } else { + NS_WARNING("Bad state of nsPluginByteRangeStreamListener"); } - NS_WARNING("Bad state of nsPluginByteRangeStreamListener"); } return mStreamConverter->OnStopRequest(request, ctxt, status); @@ -6697,5 +6736,12 @@ NS_IMETHODIMP nsPluginByteRangeStreamListener::OnDataAvailable(nsIRequest *request, nsISupports *ctxt, nsIInputStream *inStr, PRUint32 sourceOffset, PRUint32 count) { + if (!mStreamConverter) + return NS_ERROR_FAILURE; + + nsCOMPtr finalStreamListener = do_QueryReferent(mWeakPtrPluginStreamListenerPeer); + if (!finalStreamListener) + return NS_ERROR_FAILURE; + return mStreamConverter->OnDataAvailable(request, ctxt, inStr, sourceOffset, count); }