Attempting to fix bug 354380. Add safe guard against prematurely deleted scriptable plugin objects. r=mrbkap@gmail.com, sr=jonas@sicking.cc

This commit is contained in:
jst@mozilla.org 2007-08-09 15:22:26 -07:00
parent 9899ca9dd6
commit 45bb02e550
3 changed files with 49 additions and 0 deletions

View File

@ -1566,6 +1566,8 @@ _releaseobject(NPObject* npobj)
int32_t refCnt = PR_AtomicDecrement((PRInt32*)&npobj->referenceCount); int32_t refCnt = PR_AtomicDecrement((PRInt32*)&npobj->referenceCount);
if (refCnt == 0) { if (refCnt == 0) {
nsNPObjWrapper::OnDestroy(npobj);
if (npobj->_class && npobj->_class->deallocate) { if (npobj->_class && npobj->_class->deallocate) {
npobj->_class->deallocate(npobj); npobj->_class->deallocate(npobj);
} else { } else {

View File

@ -1449,6 +1449,52 @@ public:
}; };
// An NPObject is going away, make sure we null out the JS object's
// private data in case this is an NPObject that came from a plugin
// and it's destroyed prematurely.
// static
void
nsNPObjWrapper::OnDestroy(NPObject *npobj)
{
if (!npobj) {
return;
}
if (npobj->_class == &nsJSObjWrapper::sJSObjWrapperNPClass) {
// npobj is one of our own, no private data to clean up here.
return;
}
if (!sNPObjWrappers.ops) {
// No hash yet (or any more), no used wrappers available.
return;
}
NPObjWrapperHashEntry *entry =
NS_STATIC_CAST(NPObjWrapperHashEntry *,
PL_DHashTableOperate(&sNPObjWrappers, npobj,
PL_DHASH_LOOKUP));
if (PL_DHASH_ENTRY_IS_BUSY(entry) && entry->mJSObj) {
// Found a live NPObject wrapper, null out its JSObjects' private
// data.
JSContext *cx = GetJSContext(entry->mNpp);
if (cx) {
::JS_SetPrivate(cx, entry->mJSObj, nsnull);
}
// Remove the npobj from the hash now that it went away.
PL_DHashTableRawRemove(&sNPObjWrappers, entry);
OnWrapperDestroyed();
}
}
// Look up or create a JSObject that wraps the NPObject npobj. // Look up or create a JSObject that wraps the NPObject npobj.
// static // static

View File

@ -98,6 +98,7 @@ public:
class nsNPObjWrapper class nsNPObjWrapper
{ {
public: public:
static void OnDestroy(NPObject *npobj);
static JSObject *GetNewOrUsed(NPP npp, JSContext *cx, NPObject *npobj); static JSObject *GetNewOrUsed(NPP npp, JSContext *cx, NPObject *npobj);
}; };