Bug 1016524 - remove 2nd reference to object before free'ing it. r=aceman
authorJorg K <jorgk@jorgk.com>
Thu, 26 Oct 2017 23:50:50 +0200
changeset 29264 427b418a19b39c29da079e92079811991d7b5d13
parent 29263 8ec9774f4f747d1a3498a10c91dbe2d75825315c
child 29265 c468a23c5c045056e9db8d18182d2d342e324b68
push id2068
push userclokep@gmail.com
push dateMon, 13 Nov 2017 19:02:14 +0000
treeherdercomm-beta@9c7e7ce8672b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaceman
bugs1016524
Bug 1016524 - remove 2nd reference to object before free'ing it. r=aceman
mailnews/mime/src/mimemrel.cpp
--- a/mailnews/mime/src/mimemrel.cpp
+++ b/mailnews/mime/src/mimemrel.cpp
@@ -218,18 +218,34 @@ MimeMultipartRelated_finalize (MimeObjec
     relobj->output_file_stream = nullptr;
   }
 
   if (relobj->file_buffer)
   {
     relobj->file_buffer->Remove(false);
     relobj->file_buffer = nullptr;
   }
-  
+
   if (relobj->headobj) {
+    // In some error conditions when MimeMultipartRelated_parse_eof() isn't run
+    // (for example, no temp disk space available to extract message parts),
+    // the head object is also referenced as a child.
+    // If we free it, we remove the child reference first ... or crash later :-(
+    MimeContainer *cont = (MimeContainer *)relobj;
+    for (int i = 0; i < cont->nchildren; i++) {
+      if (cont->children[i] == relobj->headobj) {
+        // Shift remaining children down.
+        for (int j = i+1; j < cont->nchildren; j++) {
+          cont->children[j-1] = cont->children[j];
+        }
+        cont->children[--cont->nchildren] = nullptr;
+        break;
+      }
+    }
+
     mime_free(relobj->headobj);
     relobj->headobj = nullptr;
   }
 
   ((MimeObjectClass*)&MIME_SUPERCLASS)->finalize(obj);
 }
 
 #define ISHEX(c) ( ((c) >= '0' && (c) <= '9') || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F') )