bug 478175 - multipart/related creates duplicate child at unexpected position, resulting in confusion for multipart/alternative children. r/sr=bienvenu.
authorAndrew Sutherland <asutherland@asutherland.org>
Fri, 13 Feb 2009 17:10:33 -0800
changeset 1946 f0bdc29e9c1c
parent 1945 55d521c2e861
child 1947 e94f4c8a4a63
push id1576
push userbugmail@asutherland.org
push dateSat, 14 Feb 2009 01:12:28 +0000
treeherdercomm-central@ca4eab958e67 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs478175
bug 478175 - multipart/related creates duplicate child at unexpected position, resulting in confusion for multipart/alternative children. r/sr=bienvenu.
mailnews/mime/src/mimemrel.cpp
--- a/mailnews/mime/src/mimemrel.cpp
+++ b/mailnews/mime/src/mimemrel.cpp
@@ -245,16 +245,21 @@ MimeMultipartRelated_finalize (MimeObjec
     relobj->output_file_stream = nsnull;
   }
 
   if (relobj->file_buffer)
   {
     relobj->file_buffer->Remove(PR_FALSE);
     relobj->file_buffer = nsnull;
   }
+  
+  if (relobj->headobj) {
+    mime_free(relobj->headobj);
+    relobj->headobj = nsnull;
+  }
 
   ((MimeObjectClass*)&MIME_SUPERCLASS)->finalize(obj);
 }
 
 #define ISHEX(c) ( ((c) >= '0' && (c) <= '9') || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F') )
 #define NONHEX(c) (!ISHEX(c))
 
 extern "C" char *
@@ -995,16 +1000,17 @@ mime_multipart_related_output_fn(const c
 static int
 MimeMultipartRelated_parse_eof (MimeObject *obj, PRBool abort_p)
 {
   /* OK, all the necessary data has been collected.  We now have to spew out
      the HTML.  We let it go through all the normal mechanisms (which
      includes content-encoding handling), and intercept the output data to do
      translation of the tags.  Whee. */
   MimeMultipartRelated *relobj = (MimeMultipartRelated *) obj;
+  MimeContainer *cont = (MimeContainer *)obj;
   int status = 0;
   MimeObject *body;
   char* ct;
   const char* dct;
 
   status = ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_eof(obj, abort_p);
   if (status < 0) goto FAIL;
 
@@ -1023,20 +1029,25 @@ MimeMultipartRelated_parse_eof (MimeObje
   obj->options->output_closure = obj;
 
   body = mime_create(((ct && *ct) ? ct : (dct ? dct : TEXT_HTML)),
              relobj->buffered_hdrs, obj->options);
   if (!body) {
     status = MIME_OUT_OF_MEMORY;
     goto FAIL;
   }
-  status = ((MimeContainerClass *) obj->clazz)->add_child(obj, body);
-  if (status < 0) {
-    mime_free(body);
-    goto FAIL;
+  // replace the existing head object with the new object
+  for (int iChild = 0; iChild < cont->nchildren; iChild++) {
+    if (cont->children[iChild] == relobj->headobj) {
+      // cleanup of the headobj is performed explicitly in our finalizer now
+      //  that it does not get cleaned up as a child.
+      cont->children[iChild] = body;
+      body->parent = obj;
+      body->options = obj->options;
+    }
   }
 
   body->dontShowAsAttachment = body->clazz->displayable_inline_p(body->clazz, body->headers);
 
 #ifdef MIME_DRAFTS
   if ( obj->options &&
      obj->options->decompose_file_p &&
      obj->options->decompose_file_init_fn &&
@@ -1134,17 +1145,16 @@ FAIL:
      obj->options->decompose_file_p &&
      obj->options->decompose_file_close_fn &&
      (relobj->file_buffer || relobj->head_buffer)) {
   status = obj->options->decompose_file_close_fn ( obj->options->stream_closure );
   if (status < 0) return status;
   }
 #endif /* MIME_DRAFTS */
 
-  relobj->headobj = NULL;
   obj->options->output_fn = relobj->real_output_fn;
   obj->options->output_closure = relobj->real_output_closure;
 
   return status;
 }