Fixing not calling URLNotify with null data and also a few other times, bug 127259 r=serge sr=beard a=shaver
git-svn-id: svn://10.0.0.236/trunk@116463 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -65,6 +65,12 @@
|
||||
#include "gtkxtbin.h"
|
||||
#endif
|
||||
|
||||
// POST/GET stream type
|
||||
enum eNPPStreamTypeInternal {
|
||||
eNPPStreamTypeInternal_Get,
|
||||
eNPPStreamTypeInternal_Post
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// CID's && IID's
|
||||
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
|
||||
@@ -656,6 +662,52 @@ ns4xPlugin::GetValue(nsPluginVariable variable, void *value)
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new NPP GET or POST url stream that may have a notify callback
|
||||
NPError MakeNew4xStreamInternal (NPP npp,
|
||||
const char *relativeURL,
|
||||
const char *target,
|
||||
eNPPStreamTypeInternal type, /* GET or POST */
|
||||
PRBool bDoNotify = PR_FALSE,
|
||||
void *notifyData = nsnull,
|
||||
uint32 len = 0,
|
||||
const char *buf = nsnull,
|
||||
NPBool file = PR_FALSE)
|
||||
{
|
||||
if(!npp) return NPERR_INVALID_INSTANCE_ERROR;
|
||||
|
||||
nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata;
|
||||
|
||||
NS_ASSERTION(inst != NULL, "null instance");
|
||||
if (inst == NULL)
|
||||
return NPERR_INVALID_INSTANCE_ERROR;
|
||||
|
||||
nsCOMPtr<nsIPluginManager> pm = do_GetService(kPluginManagerCID);
|
||||
NS_ASSERTION(pm, "failed to get plugin manager");
|
||||
if (!pm) return NPERR_GENERIC_ERROR;
|
||||
|
||||
nsIPluginStreamListener* listener = nsnull;
|
||||
if(target == nsnull)
|
||||
((ns4xPluginInstance*)inst)->NewNotifyStream(&listener, notifyData, bDoNotify);
|
||||
|
||||
switch (type) {
|
||||
case eNPPStreamTypeInternal_Get:
|
||||
{
|
||||
if(NS_FAILED(pm->GetURL(inst, relativeURL, target, listener)))
|
||||
return NPERR_GENERIC_ERROR;
|
||||
break;
|
||||
}
|
||||
case eNPPStreamTypeInternal_Post:
|
||||
{
|
||||
if(NS_FAILED(pm->PostURL(inst, relativeURL, len, buf, file, target, listener)))
|
||||
return NPERR_GENERIC_ERROR;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
NS_ASSERTION(0, "how'd I get here");
|
||||
}
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -668,33 +720,7 @@ _geturl(NPP npp, const char* relativeURL, const char* target)
|
||||
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
||||
("NPN_GetURL: npp=%p, target=%s, url=%s\n", (void *)npp, target, relativeURL));
|
||||
|
||||
if(!npp)
|
||||
return NPERR_INVALID_INSTANCE_ERROR;
|
||||
|
||||
nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata;
|
||||
|
||||
NS_ASSERTION(inst != NULL, "null instance");
|
||||
NS_ASSERTION(gServiceMgr != NULL, "null service manager");
|
||||
|
||||
if (inst == NULL)
|
||||
return NPERR_INVALID_INSTANCE_ERROR;
|
||||
|
||||
if(gServiceMgr == nsnull)
|
||||
return NPERR_GENERIC_ERROR;
|
||||
|
||||
nsIPluginStreamListener* listener = nsnull;
|
||||
if(target == nsnull)
|
||||
inst->NewStream(&listener);
|
||||
|
||||
nsIPluginManager * pm;
|
||||
gServiceMgr->GetService(kPluginManagerCID, kIPluginManagerIID, (nsISupports**)&pm);
|
||||
|
||||
if(pm->GetURL(inst, relativeURL, target, listener) != NS_OK)
|
||||
return NPERR_GENERIC_ERROR;
|
||||
|
||||
NS_RELEASE(pm);
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
return MakeNew4xStreamInternal (npp, relativeURL, target, eNPPStreamTypeInternal_Get);
|
||||
}
|
||||
|
||||
|
||||
@@ -705,33 +731,7 @@ _geturlnotify(NPP npp, const char* relativeURL, const char* target, void* notify
|
||||
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
||||
("NPN_GetURLNotify: npp=%p, target=%s, notify=%p, url=%s\n", (void*)npp, target, notifyData, relativeURL));
|
||||
|
||||
if(!npp)
|
||||
return NPERR_INVALID_INSTANCE_ERROR;
|
||||
|
||||
nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata;
|
||||
|
||||
NS_ASSERTION(inst != NULL, "null instance");
|
||||
NS_ASSERTION(gServiceMgr != NULL, "null service manager");
|
||||
|
||||
if (inst == NULL)
|
||||
return NPERR_INVALID_INSTANCE_ERROR;
|
||||
|
||||
if(gServiceMgr == nsnull)
|
||||
return NPERR_GENERIC_ERROR;
|
||||
|
||||
nsIPluginStreamListener* listener = nsnull;
|
||||
if(target == nsnull)
|
||||
((ns4xPluginInstance*)inst)->NewNotifyStream(&listener, notifyData);
|
||||
|
||||
nsIPluginManager * pm;
|
||||
gServiceMgr->GetService(kPluginManagerCID, kIPluginManagerIID, (nsISupports**)&pm);
|
||||
|
||||
if(pm->GetURL(inst, relativeURL, target, listener) != NS_OK)
|
||||
return NPERR_GENERIC_ERROR;
|
||||
|
||||
NS_RELEASE(pm);
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
return MakeNew4xStreamInternal (npp, relativeURL, target, eNPPStreamTypeInternal_Get, PR_TRUE, notifyData);
|
||||
}
|
||||
|
||||
|
||||
@@ -744,33 +744,8 @@ _posturlnotify(NPP npp, const char *relativeURL, const char *target,
|
||||
("NPN_PostURLNotify: npp=%p, target=%s, len=%d, file=%d, notify=%p, url=%s, buf=%s\n",
|
||||
(void*)npp, target, len, file, notifyData, relativeURL, buf));
|
||||
|
||||
if(!npp)
|
||||
return NPERR_INVALID_INSTANCE_ERROR;
|
||||
|
||||
nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata;
|
||||
|
||||
NS_ASSERTION(inst != NULL, "null instance");
|
||||
NS_ASSERTION(gServiceMgr != NULL, "null service manager");
|
||||
|
||||
if (inst == NULL)
|
||||
return NPERR_INVALID_INSTANCE_ERROR;
|
||||
|
||||
if(gServiceMgr == nsnull)
|
||||
return NPERR_GENERIC_ERROR;
|
||||
|
||||
nsIPluginStreamListener* listener = nsnull;
|
||||
if(target == nsnull)
|
||||
((ns4xPluginInstance*)inst)->NewNotifyStream(&listener, notifyData);
|
||||
|
||||
nsIPluginManager * pm;
|
||||
gServiceMgr->GetService(kPluginManagerCID, kIPluginManagerIID, (nsISupports**)&pm);
|
||||
|
||||
if(pm->PostURL(inst, relativeURL, len, buf, file, target, listener) != NS_OK)
|
||||
return NPERR_GENERIC_ERROR;
|
||||
|
||||
NS_RELEASE(pm);
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
return MakeNew4xStreamInternal (npp, relativeURL, target, eNPPStreamTypeInternal_Post,
|
||||
PR_TRUE, notifyData, len, buf, file);
|
||||
}
|
||||
|
||||
|
||||
@@ -783,33 +758,8 @@ _posturl(NPP npp, const char *relativeURL, const char *target,
|
||||
("NPN_PostURL: npp=%p, target=%s, file=%d, len=%d, url=%s, buf=%s\n",
|
||||
(void*)npp, target, file, len, relativeURL, buf));
|
||||
|
||||
if(!npp)
|
||||
return NPERR_INVALID_INSTANCE_ERROR;
|
||||
|
||||
nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata;
|
||||
|
||||
NS_ASSERTION(inst != NULL, "null instance");
|
||||
NS_ASSERTION(gServiceMgr != NULL, "null service manager");
|
||||
|
||||
if (inst == NULL)
|
||||
return NPERR_INVALID_INSTANCE_ERROR;
|
||||
|
||||
if(gServiceMgr == nsnull)
|
||||
return NPERR_GENERIC_ERROR;
|
||||
|
||||
nsIPluginStreamListener* listener = nsnull;
|
||||
if(target == nsnull)
|
||||
inst->NewStream(&listener);
|
||||
|
||||
nsIPluginManager * pm;
|
||||
gServiceMgr->GetService(kPluginManagerCID, kIPluginManagerIID, (nsISupports**)&pm);
|
||||
|
||||
if(pm->PostURL(inst, relativeURL, len, buf, file, target, listener) != NS_OK)
|
||||
return NPERR_GENERIC_ERROR;
|
||||
|
||||
NS_RELEASE(pm);
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
return MakeNew4xStreamInternal (npp, relativeURL, target, eNPPStreamTypeInternal_Post,
|
||||
PR_FALSE, nsnull, len, buf, file);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -82,7 +82,8 @@ ns4xPluginStreamListener::ns4xPluginStreamListener(nsIPluginInstance* inst,
|
||||
: mNotifyData(notifyData),
|
||||
mStreamStarted(PR_FALSE),
|
||||
mStreamCleanedUp(PR_FALSE),
|
||||
mStreamInfo(nsnull)
|
||||
mStreamInfo(nsnull),
|
||||
mCallNotify(PR_FALSE)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mInst = (ns4xPluginInstance*) inst;
|
||||
@@ -100,12 +101,13 @@ ns4xPluginStreamListener::ns4xPluginStreamListener(nsIPluginInstance* inst,
|
||||
ns4xPluginStreamListener::~ns4xPluginStreamListener(void)
|
||||
{
|
||||
// remove itself from the instance stream list
|
||||
if(mInst) {
|
||||
ns4xPluginInstance *inst = mInst;
|
||||
if(inst) {
|
||||
nsInstanceStream * prev = nsnull;
|
||||
for(nsInstanceStream *is = mInst->mStreams; is != nsnull; is = is->mNext) {
|
||||
for(nsInstanceStream *is = inst->mStreams; is != nsnull; is = is->mNext) {
|
||||
if(is->mPluginStreamListener == this) {
|
||||
if(prev == nsnull)
|
||||
mInst->mStreams = is->mNext;
|
||||
inst->mStreams = is->mNext;
|
||||
else
|
||||
prev->mNext = is->mNext;
|
||||
|
||||
@@ -115,7 +117,13 @@ ns4xPluginStreamListener::~ns4xPluginStreamListener(void)
|
||||
prev = is;
|
||||
}
|
||||
}
|
||||
NS_IF_RELEASE(mInst);
|
||||
|
||||
// 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 called for other reasons elsewhere.
|
||||
CallURLNotify(NPRES_NETWORK_ERR);
|
||||
|
||||
NS_IF_RELEASE(inst);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -155,22 +163,6 @@ nsresult ns4xPluginStreamListener::CleanUpStream(NPReason reason)
|
||||
rv = NS_OK;
|
||||
}
|
||||
|
||||
// check to see if we have a callback
|
||||
if (callbacks->urlnotify && mNotifyData) {
|
||||
PRLibrary* lib = nsnull;
|
||||
lib = mInst->fLibrary;
|
||||
|
||||
NS_TRY_SAFE_CALL_VOID(CallNPP_URLNotifyProc(callbacks->urlnotify,
|
||||
npp,
|
||||
mNPStream.url,
|
||||
nsPluginReason_Done,
|
||||
mNotifyData), lib);
|
||||
|
||||
NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
||||
("NPP URLNotify called: this=%p, npp=%p, notify=%p, url=%s\n",
|
||||
this, npp, mNotifyData, mNPStream.url));
|
||||
}
|
||||
|
||||
// lets get rid of the buffer if we made one globally
|
||||
if (mStreamBuffer)
|
||||
{
|
||||
@@ -180,10 +172,51 @@ nsresult ns4xPluginStreamListener::CleanUpStream(NPReason reason)
|
||||
|
||||
mStreamCleanedUp = PR_TRUE;
|
||||
mStreamStarted = PR_FALSE;
|
||||
|
||||
// fire notification back to plugin, just like before
|
||||
CallURLNotify(reason);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void ns4xPluginStreamListener::CallURLNotify(NPReason reason)
|
||||
{
|
||||
if(!mCallNotify || !mInst || !mInst->IsStarted())
|
||||
return;
|
||||
|
||||
mCallNotify = PR_FALSE; // only do this ONCE and prevent recursion
|
||||
|
||||
const NPPluginFuncs *callbacks = nsnull;
|
||||
mInst->GetCallbacks(&callbacks);
|
||||
if(!callbacks)
|
||||
return;
|
||||
|
||||
NPP npp;
|
||||
mInst->GetNPP(&npp);
|
||||
|
||||
if (callbacks->urlnotify) {
|
||||
PRLibrary* lib = mInst->fLibrary;
|
||||
|
||||
NS_TRY_SAFE_CALL_VOID(CallNPP_URLNotifyProc(callbacks->urlnotify,
|
||||
npp,
|
||||
mNPStream.url,
|
||||
reason,
|
||||
mNotifyData), lib);
|
||||
|
||||
NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
||||
("NPP URLNotify called: this=%p, npp=%p, notify=%p, reason=%d, url=%s\n",
|
||||
this, npp, mNotifyData, reason, mNPStream.url));
|
||||
}
|
||||
|
||||
// Let's not leak this stream listener. Release the reference to the stream listener
|
||||
// added for the notify callback in NewNotifyStream.
|
||||
// Note: This may destroy us if we are not being destroyed already.
|
||||
NS_RELEASE_THIS();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
NS_IMETHODIMP
|
||||
ns4xPluginStreamListener::OnStartBinding(nsIPluginStreamInfo* pluginInfo)
|
||||
@@ -762,13 +795,17 @@ NS_IMETHODIMP ns4xPluginInstance::Stop(void)
|
||||
|
||||
// clean up open streams
|
||||
for(nsInstanceStream *is = mStreams; is != nsnull;) {
|
||||
if(is->mPluginStreamListener)
|
||||
is->mPluginStreamListener->CleanUpStream(NPRES_USER_BREAK);
|
||||
ns4xPluginStreamListener * 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);
|
||||
}
|
||||
|
||||
NS_TRY_SAFE_CALL_RETURN(error, CallNPP_DestroyProc(fCallbacks->destroy, &fNPP, &sdata), fLibrary);
|
||||
@@ -1039,7 +1076,7 @@ NS_IMETHODIMP ns4xPluginInstance::SetWindow(nsPluginWindow* window)
|
||||
|
||||
NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
||||
("NPP SetWindow called: this=%p, [x=%d,y=%d,w=%d,h=%d], clip[t=%d,b=%d,l=%d,r=%d], return=%d\n",
|
||||
this, &fNPP, window->x, window->y, window->width, window->height,
|
||||
this, window->x, window->y, window->width, window->height,
|
||||
window->clipRect.top, window->clipRect.bottom, window->clipRect.left, window->clipRect.right, error));
|
||||
|
||||
// XXX In the old code, we'd just ignore any errors coming
|
||||
@@ -1052,29 +1089,30 @@ NS_IMETHODIMP ns4xPluginInstance::SetWindow(nsPluginWindow* window)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/* NOTE: the caller must free the stream listener */
|
||||
// Create a normal stream, one without a urlnotify callback
|
||||
NS_IMETHODIMP ns4xPluginInstance::NewStream(nsIPluginStreamListener** listener)
|
||||
{
|
||||
return NewNotifyStream(listener, nsnull);
|
||||
return NewNotifyStream(listener, nsnull, PR_FALSE);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
nsresult ns4xPluginInstance::NewNotifyStream(nsIPluginStreamListener** listener, void* notifyData)
|
||||
// Create a stream that will notify when complete
|
||||
nsresult ns4xPluginInstance::NewNotifyStream(nsIPluginStreamListener** listener,
|
||||
void* notifyData,
|
||||
PRBool aCallNotify)
|
||||
{
|
||||
ns4xPluginStreamListener* stream = new ns4xPluginStreamListener(this, notifyData);
|
||||
|
||||
if(stream == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ENSURE_TRUE(stream, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// add it to the list
|
||||
nsInstanceStream * is = new nsInstanceStream();
|
||||
|
||||
if(!is)
|
||||
return NS_ERROR_FAILURE;
|
||||
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
|
||||
|
||||
NS_ADDREF(stream); // Stabilize
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ public:
|
||||
|
||||
nsresult SetTransparent(PRBool aTransparent);
|
||||
|
||||
nsresult NewNotifyStream(nsIPluginStreamListener** listener, void* notifyData);
|
||||
nsresult NewNotifyStream(nsIPluginStreamListener** listener, void* notifyData, PRBool aCallNotify);
|
||||
|
||||
/**
|
||||
* Construct a new 4.x plugin instance with the specified peer
|
||||
|
||||
@@ -64,6 +64,8 @@ public:
|
||||
virtual ~ns4xPluginStreamListener();
|
||||
PRBool IsStarted();
|
||||
nsresult CleanUpStream(NPReason reason);
|
||||
void CallURLNotify(NPReason reason);
|
||||
void SetCallNotify(PRBool aCallNotify) { mCallNotify = aCallNotify; }
|
||||
|
||||
protected:
|
||||
void* mNotifyData;
|
||||
@@ -75,6 +77,7 @@ protected:
|
||||
nsPluginStreamType mStreamType;
|
||||
PRBool mStreamStarted;
|
||||
PRBool mStreamCleanedUp;
|
||||
PRBool mCallNotify;
|
||||
|
||||
public:
|
||||
nsIPluginStreamInfo * mStreamInfo;
|
||||
|
||||
Reference in New Issue
Block a user