Bug 755961: Plugin stream decomtamination (nsIPluginStreamListener). r=bsmedberg
This commit is contained in:
@@ -56,7 +56,6 @@
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
#include "nsIPluginStreamListener.h"
|
||||
#include "nsPluginsDir.h"
|
||||
#include "nsPluginSafety.h"
|
||||
#include "nsPluginLogging.h"
|
||||
@@ -561,10 +560,13 @@ nsNPAPIPlugin::RetainStream(NPStream *pstream, nsISupports **aRetainedPeer)
|
||||
if (!pstream || !pstream->ndata)
|
||||
return NPERR_INVALID_PARAM;
|
||||
|
||||
nsNPAPIPluginStreamListener* listener =
|
||||
static_cast<nsNPAPIPluginStreamListener*>(pstream->ndata);
|
||||
nsPluginStreamListenerPeer* peer = listener->GetStreamListenerPeer();
|
||||
nsNPAPIStreamWrapper* streamWrapper = static_cast<nsNPAPIStreamWrapper*>(pstream->ndata);
|
||||
nsNPAPIPluginStreamListener* listener = streamWrapper->GetStreamListener();
|
||||
if (!listener) {
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
nsPluginStreamListenerPeer* peer = listener->GetStreamListenerPeer();
|
||||
if (!peer)
|
||||
return NPERR_GENERIC_ERROR;
|
||||
|
||||
@@ -597,7 +599,7 @@ MakeNewNPAPIStreamInternal(NPP npp, const char *relativeURL, const char *target,
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPluginStreamListener> listener;
|
||||
nsRefPtr<nsNPAPIPluginStreamListener> listener;
|
||||
// Set aCallNotify here to false. If pluginHost->GetURL or PostURL fail,
|
||||
// the listener's destructor will do the notification while we are about to
|
||||
// return a failure code.
|
||||
@@ -607,7 +609,7 @@ MakeNewNPAPIStreamInternal(NPP npp, const char *relativeURL, const char *target,
|
||||
inst->NewStreamListener(relativeURL, notifyData,
|
||||
getter_AddRefs(listener));
|
||||
if (listener) {
|
||||
static_cast<nsNPAPIPluginStreamListener*>(listener.get())->SetCallNotify(false);
|
||||
listener->SetCallNotify(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -631,7 +633,7 @@ MakeNewNPAPIStreamInternal(NPP npp, const char *relativeURL, const char *target,
|
||||
|
||||
if (listener) {
|
||||
// SetCallNotify(bDoNotify) here, see comment above.
|
||||
static_cast<nsNPAPIPluginStreamListener*>(listener.get())->SetCallNotify(bDoNotify);
|
||||
listener->SetCallNotify(bDoNotify);
|
||||
}
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
@@ -645,25 +647,6 @@ namespace {
|
||||
|
||||
static char *gNPPException;
|
||||
|
||||
// A little helper class used to wrap up plugin manager streams (that is,
|
||||
// streams from the plugin to the browser).
|
||||
class nsNPAPIStreamWrapper : nsISupports
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
protected:
|
||||
nsIOutputStream *fStream;
|
||||
NPStream fNPStream;
|
||||
|
||||
public:
|
||||
nsNPAPIStreamWrapper(nsIOutputStream* stream);
|
||||
virtual ~nsNPAPIStreamWrapper();
|
||||
|
||||
void GetStream(nsIOutputStream* &result);
|
||||
NPStream* GetNPStream() { return &fNPStream; }
|
||||
};
|
||||
|
||||
class nsPluginThreadRunnable : public nsRunnable,
|
||||
public PRCList
|
||||
{
|
||||
@@ -770,33 +753,6 @@ InHeap(HANDLE hHeap, LPVOID lpMem)
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsNPAPIStreamWrapper, nsISupports)
|
||||
|
||||
nsNPAPIStreamWrapper::nsNPAPIStreamWrapper(nsIOutputStream* stream)
|
||||
: fStream(stream)
|
||||
{
|
||||
NS_ASSERTION(stream, "bad stream");
|
||||
|
||||
fStream = stream;
|
||||
NS_ADDREF(fStream);
|
||||
|
||||
memset(&fNPStream, 0, sizeof(fNPStream));
|
||||
fNPStream.ndata = (void*) this;
|
||||
}
|
||||
|
||||
nsNPAPIStreamWrapper::~nsNPAPIStreamWrapper()
|
||||
{
|
||||
fStream->Close();
|
||||
NS_IF_RELEASE(fStream);
|
||||
}
|
||||
|
||||
void
|
||||
nsNPAPIStreamWrapper::GetStream(nsIOutputStream* &result)
|
||||
{
|
||||
result = fStream;
|
||||
NS_IF_ADDREF(fStream);
|
||||
}
|
||||
|
||||
NPPExceptionAutoHolder::NPPExceptionAutoHolder()
|
||||
: mOldException(gNPPException)
|
||||
{
|
||||
@@ -1067,9 +1023,9 @@ _newstream(NPP npp, NPMIMEType type, const char* target, NPStream* *result)
|
||||
nsCOMPtr<nsIOutputStream> stream;
|
||||
if (NS_SUCCEEDED(inst->NewStreamFromPlugin((const char*) type, target,
|
||||
getter_AddRefs(stream)))) {
|
||||
nsNPAPIStreamWrapper* wrapper = new nsNPAPIStreamWrapper(stream);
|
||||
nsNPAPIStreamWrapper* wrapper = new nsNPAPIStreamWrapper(stream, nsnull);
|
||||
if (wrapper) {
|
||||
(*result) = wrapper->GetNPStream();
|
||||
(*result) = &wrapper->mNPStream;
|
||||
err = NPERR_NO_ERROR;
|
||||
} else {
|
||||
err = NPERR_OUT_OF_MEMORY_ERROR;
|
||||
@@ -1098,20 +1054,22 @@ _write(NPP npp, NPStream *pstream, int32_t len, void *buffer)
|
||||
|
||||
PluginDestructionGuard guard(npp);
|
||||
|
||||
nsNPAPIStreamWrapper* wrapper = (nsNPAPIStreamWrapper*) pstream->ndata;
|
||||
NS_ASSERTION(wrapper, "null stream");
|
||||
if (!wrapper)
|
||||
nsNPAPIStreamWrapper* wrapper = static_cast<nsNPAPIStreamWrapper*>(pstream->ndata);
|
||||
if (!wrapper) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
nsIOutputStream* stream;
|
||||
wrapper->GetStream(stream);
|
||||
nsIOutputStream* stream = wrapper->GetOutputStream();
|
||||
if (!stream) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
PRUint32 count = 0;
|
||||
nsresult rv = stream->Write((char *)buffer, len, &count);
|
||||
NS_RELEASE(stream);
|
||||
|
||||
if (rv != NS_OK)
|
||||
if (NS_FAILED(rv)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (int32_t)count;
|
||||
}
|
||||
@@ -1132,34 +1090,24 @@ _destroystream(NPP npp, NPStream *pstream, NPError reason)
|
||||
|
||||
PluginDestructionGuard guard(npp);
|
||||
|
||||
nsCOMPtr<nsIPluginStreamListener> listener =
|
||||
do_QueryInterface((nsISupports *)pstream->ndata);
|
||||
nsNPAPIStreamWrapper *streamWrapper = static_cast<nsNPAPIStreamWrapper*>(pstream->ndata);
|
||||
if (!streamWrapper) {
|
||||
return NPERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
// DestroyStream can kill two kinds of streams: NPP derived and NPN derived.
|
||||
// check to see if they're trying to kill a NPP stream
|
||||
nsRefPtr<nsNPAPIPluginStreamListener> listener = streamWrapper->GetStreamListener();
|
||||
if (listener) {
|
||||
// Tell the stream listner that the stream is now gone.
|
||||
listener->OnStopBinding(nsnull, NS_BINDING_ABORTED);
|
||||
|
||||
// FIXME: http://bugzilla.mozilla.org/show_bug.cgi?id=240131
|
||||
//
|
||||
// Is it ok to leave pstream->ndata set here, and who releases it
|
||||
// (or is it even properly ref counted)? And who closes the stream
|
||||
// etc?
|
||||
} else {
|
||||
nsNPAPIStreamWrapper* wrapper = (nsNPAPIStreamWrapper *)pstream->ndata;
|
||||
NS_ASSERTION(wrapper, "null wrapper");
|
||||
|
||||
if (!wrapper)
|
||||
return NPERR_INVALID_PARAM;
|
||||
|
||||
// This will release the wrapped nsIOutputStream.
|
||||
// pstream should always be a subobject of wrapper. See bug 548441.
|
||||
NS_ASSERTION((char*)wrapper <= (char*)pstream &&
|
||||
NS_ASSERTION((char*)streamWrapper <= (char*)pstream &&
|
||||
((char*)pstream) + sizeof(*pstream)
|
||||
<= ((char*)wrapper) + sizeof(*wrapper),
|
||||
<= ((char*)streamWrapper) + sizeof(*streamWrapper),
|
||||
"pstream is not a subobject of wrapper");
|
||||
delete wrapper;
|
||||
delete streamWrapper;
|
||||
}
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
@@ -2571,7 +2519,11 @@ _requestread(NPStream *pstream, NPByteRange *rangeList)
|
||||
if (!pstream || !rangeList || !pstream->ndata)
|
||||
return NPERR_INVALID_PARAM;
|
||||
|
||||
nsNPAPIPluginStreamListener* streamlistener = (nsNPAPIPluginStreamListener*)pstream->ndata;
|
||||
nsNPAPIStreamWrapper* streamWrapper = static_cast<nsNPAPIStreamWrapper*>(pstream->ndata);
|
||||
nsNPAPIPluginStreamListener* streamlistener = streamWrapper->GetStreamListener();
|
||||
if (!streamlistener) {
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
PRInt32 streamtype = NP_NORMAL;
|
||||
|
||||
@@ -2583,8 +2535,7 @@ _requestread(NPStream *pstream, NPByteRange *rangeList)
|
||||
if (!streamlistener->mStreamInfo)
|
||||
return NPERR_GENERIC_ERROR;
|
||||
|
||||
nsresult rv = streamlistener->mStreamInfo
|
||||
->RequestRead((NPByteRange *)rangeList);
|
||||
nsresult rv = streamlistener->mStreamInfo->RequestRead((NPByteRange *)rangeList);
|
||||
if (NS_FAILED(rv))
|
||||
return NPERR_GENERIC_ERROR;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user