Bug 453196, prevent hangs when attachment snarfing fails, r=jorgk a=jorgk
authorR Kent James <rkent@caspia.com>
Tue, 21 Jun 2016 18:01:52 -0700
changeset 27241 999a626ee96077530ddaf3603a8169138370e049
parent 27240 10cbb73a354b0b7ae31afb341e02ae14125db0ff
child 27242 4fdb71bcd424fa76979142d46e8e1b776d0f2eb6
push id1850
push userclokep@gmail.com
push dateWed, 08 Mar 2017 19:29:12 +0000
treeherdercomm-esr52@028df196b2d9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorgk, jorgk
bugs453196
Bug 453196, prevent hangs when attachment snarfing fails, r=jorgk a=jorgk
mailnews/compose/src/nsMsgAttachmentHandler.cpp
mailnews/compose/test/unit/head_compose.js
mailnews/compose/test/unit/test_messageHeaders.js
mailnews/imap/src/nsImapProtocol.cpp
mailnews/mime/src/nsStreamConverter.cpp
--- a/mailnews/compose/src/nsMsgAttachmentHandler.cpp
+++ b/mailnews/compose/src/nsMsgAttachmentHandler.cpp
@@ -1125,16 +1125,20 @@ nsMsgAttachmentHandler::UrlExit(nsresult
     m_charset = nsMsgI18NParseMetaCharset(mTmpFile);
 
   nsresult mimeDeliveryStatus;
   m_mime_delivery_state->GetStatus(&mimeDeliveryStatus);
 
   if (mimeDeliveryStatus == NS_ERROR_ABORT)
     status = NS_ERROR_ABORT;
 
+  // If the attachment is empty, let's call that a failure.
+  if (!m_size)
+    status = NS_ERROR_FAILURE;
+
   if (NS_FAILED(status) && status != NS_ERROR_ABORT && NS_SUCCEEDED(mimeDeliveryStatus))
   {
     // At this point, we should probably ask a question to the user
     // if we should continue without this attachment.
     //
     bool              keepOnGoing = true;
     nsCString    turl;
     nsString     msg;
--- a/mailnews/compose/test/unit/head_compose.js
+++ b/mailnews/compose/test/unit/head_compose.js
@@ -135,17 +135,17 @@ function createMessage(aAttachment) {
   if (aAttachment) {
     let attachment = Cc["@mozilla.org/messengercompose/attachment;1"]
                        .createInstance(Ci.nsIMsgAttachment);
     if (aAttachment instanceof Ci.nsIFile) {
       attachment.url = "file://" + aAttachment.path;
       attachment.contentType = 'text/plain';
       attachment.name = aAttachment.leafName;
     } else {
-      attachment.url = "data:,";
+      attachment.url = "data:,sometext";
       attachment.name = aAttachment;
     }
     attachments = [attachment];
   }
   return richCreateMessage(fields, attachments);
 }
 
 function richCreateMessage(fields, attachments=[], identity=null,
--- a/mailnews/compose/test/unit/test_messageHeaders.js
+++ b/mailnews/compose/test/unit/test_messageHeaders.js
@@ -370,24 +370,24 @@ function* testContentHeaders() {
 
   plainAttachment.name = "\ud83d\udca9.txt";
   plainAttachmentHeaders["Content-Disposition"] =
     "attachment; filename*=UTF-8''%F0%9F%92%A9%2E%74%78%74";
   yield richCreateMessage(fields, [plainAttachment], identity);
   checkDraftHeaders(plainAttachmentHeaders, "2");
 
   let httpAttachment = makeAttachment({
-    url: "data:text/html,",
+    url: "data:text/html,<html><body></body></html>",
     name: "attachment.html",
   });
   let httpAttachmentHeaders = {
     "Content-Type": "text/html",
     "Content-Disposition": "attachment; filename=\"attachment.html\"",
-    "Content-Base": '"data:text/html,"',
-    "Content-Location": '"data:text/html,"',
+    "Content-Base": '"data:text/html,<html><body></body></html>"',
+    "Content-Location": '"data:text/html,<html><body></body></html>"',
   };
   yield richCreateMessage(fields, [httpAttachment], identity);
   checkDraftHeaders({
     "Content-Base": undefined,
     "Content-Location": undefined
   }, "1");
   checkDraftHeaders(httpAttachmentHeaders, "2");
 
--- a/mailnews/imap/src/nsImapProtocol.cpp
+++ b/mailnews/imap/src/nsImapProtocol.cpp
@@ -9275,17 +9275,17 @@ nsresult nsImapMockChannel::ReadFromImap
   // loading the url consists of asking the server to add the url to it's imap event queue....
   nsCOMPtr<nsIMsgIncomingServer> server;
   rv = mailnewsUrl->GetServer(getter_AddRefs(server));
   NS_ENSURE_SUCCESS(rv, rv);
   nsCOMPtr<nsIImapIncomingServer> imapServer (do_QueryInterface(server, &rv));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Assume AsyncRead is always called from the UI thread.....
-  return imapServer->GetImapConnectionAndLoadUrl(imapUrl, nullptr);
+  return imapServer->GetImapConnectionAndLoadUrl(imapUrl, m_channelListener);
 }
 
 // for messages stored in our offline cache, we have special code to handle that...
 // If it's in the local cache, we return true and we can abort the download because
 // this method does the rest of the work.
 bool nsImapMockChannel::ReadFromLocalCache()
 {
   nsresult rv = NS_OK;
--- a/mailnews/mime/src/nsStreamConverter.cpp
+++ b/mailnews/mime/src/nsStreamConverter.cpp
@@ -994,16 +994,18 @@ nsStreamConverter::OnStartRequest(nsIReq
 
 //
 // Notify the observer that the URL has finished loading.  This method is
 // called once when the networking library has finished processing the
 //
 nsresult
 nsStreamConverter::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult status)
 {
+  // Make sure we fire any pending OnStartRequest before we do OnStop.
+  FirePendingStartRequest();
 #ifdef DEBUG_rhp
     printf("nsStreamConverter::OnStopRequest()\n");
 #endif
 
   //
   // Now complete the stream!
   //
   if (mBridgeStream)