Bug 542915 - 'Protect DelayedReleaseGCCallback from reentering and double-freeing NPObjects' r=jst+josh.
authorBen Turner <bent.mozilla@gmail.com>
Mon, 01 Feb 2010 12:35:48 -0800
changeset 46634 5bc1c351482222249da2cee9903794318ff50719
parent 46633 95990e1a50e5647fc6c3b3dcc73ca92c518f8251
child 46635 c2d2de888c99294c67ee75ad10f7ceb4acb2fe90
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersjst
bugs542915
milestone1.9.3a1pre
Bug 542915 - 'Protect DelayedReleaseGCCallback from reentering and double-freeing NPObjects' r=jst+josh.
modules/plugin/base/src/nsJSNPRuntime.cpp
--- a/modules/plugin/base/src/nsJSNPRuntime.cpp
+++ b/modules/plugin/base/src/nsJSNPRuntime.cpp
@@ -202,25 +202,28 @@ static JSClass sNPObjectMemberClass =
 
 static void
 OnWrapperDestroyed();
 
 static JSBool
 DelayedReleaseGCCallback(JSContext* cx, JSGCStatus status)
 {
   if (JSGC_END == status) {
-    if (sDelayedReleases) {
-      for (PRInt32 i = 0; i < sDelayedReleases->Length(); ++i) {
-        NPObject* obj = (*sDelayedReleases)[i];
+    // Take ownership of sDelayedReleases and null it out now. The
+    // _releaseobject call below can reenter GC and double-free these objects.
+    nsAutoPtr<nsTArray<NPObject*> > delayedReleases(sDelayedReleases);
+    sDelayedReleases = nsnull;
+
+    if (delayedReleases) {
+      for (PRUint32 i = 0; i < delayedReleases->Length(); ++i) {
+        NPObject* obj = (*delayedReleases)[i];
         if (obj)
           _releaseobject(obj);
         OnWrapperDestroyed();
       }
-      delete sDelayedReleases;
-      sDelayedReleases = NULL;
     }
   }
   return JS_TRUE;
 }
 
 static void
 OnWrapperCreated()
 {