Bug 1444379 - add error checking to call sites of GetDefaultPrompt() to avoid crash in nsMsgComposeAndSend::NotifyListenerOnStopCopy() and elsewhere. r=jorgk
authorMagnus Melin <mkmelin+mozilla@iki.fi>
Fri, 28 Sep 2018 15:42:29 +0300
changeset 33256 42792e593b1acf771d6a8ef560663d6a60162d3d
parent 33255 4a2171ca49dac042b79ce673444c0e62ebab613f
child 33257 ea04f95d5ceb814eeb22e47d72b5e3fa5418ce46
push id387
push userclokep@gmail.com
push dateMon, 10 Dec 2018 21:30:47 +0000
reviewersjorgk
bugs1444379
Bug 1444379 - add error checking to call sites of GetDefaultPrompt() to avoid crash in nsMsgComposeAndSend::NotifyListenerOnStopCopy() and elsewhere. r=jorgk Especially for the shutdown case, it may not be possible to get a prompt
mailnews/compose/src/nsMsgSend.cpp
--- a/mailnews/compose/src/nsMsgSend.cpp
+++ b/mailnews/compose/src/nsMsgSend.cpp
@@ -457,24 +457,21 @@ nsMsgComposeAndSend::GatherMimeAttachmen
   nsMsgSendPart* plainpart = nullptr;    // If we converted HTML into plaintext,
                       // the message or child containing the plaintext
                       // goes here. (Need to use this to determine
                       // what headers to append/set to the main
                       // message body.)
 
   uint32_t multipartRelatedCount = GetMultipartRelatedCount(); // The number of related part we will have to generate
 
-  nsCOMPtr<nsIPrompt> promptObject; // only used if we have to show an alert here....
-  GetDefaultPrompt(getter_AddRefs(promptObject));
-
   char *hdrs = 0;
   bool maincontainerISrelatedpart = false;
   const char * toppart_type = nullptr;
-
   status = m_status;
+
   if (NS_FAILED(status))
     goto FAIL;
 
   if (!m_attachment1_type) {
     m_attachment1_type = PL_strdup(TEXT_PLAIN);
     if (!m_attachment1_type)
       goto FAILMEM;
   }
@@ -3199,17 +3196,18 @@ nsMsgComposeAndSend::DeliverMessage()
     FormatFileSize(fileSize, true, formattedFileSize);
     const char16_t* params[] = { formattedFileSize.get() };
     mComposeBundle->FormatStringFromName("largeMessageSendWarning",
                                          params, 1, msg);
 
     if (!msg.IsEmpty())
     {
       nsCOMPtr<nsIPrompt> prompt;
-      GetDefaultPrompt(getter_AddRefs(prompt));
+      rv = GetDefaultPrompt(getter_AddRefs(prompt));
+      NS_ENSURE_SUCCESS(rv, rv);
       nsMsgAskBooleanQuestionByString(prompt, msg.get(), &abortTheSend);
       if (!abortTheSend)
       {
         nsresult ignoreMe;
         Fail(NS_ERROR_BUT_DONT_SHOW_ALERT, msg.get(), &ignoreMe);
         return NS_ERROR_FAILURE;
       }
     }
@@ -3237,19 +3235,16 @@ nsMsgComposeAndSend::DeliverFileAsMail()
   buf = (char *) PR_Malloc ((mCompFields->GetTo() ? PL_strlen (mCompFields->GetTo())  + 10 : 0) +
                (mCompFields->GetCc() ? PL_strlen (mCompFields->GetCc())  + 10 : 0) +
                (mCompFields->GetBcc() ? PL_strlen (mCompFields->GetBcc()) + 10 : 0) +
                10);
 
   if (mSendReport)
     mSendReport->SetCurrentProcess(nsIMsgSendReport::process_SMTP);
 
-  nsCOMPtr<nsIPrompt> promptObject;
-  GetDefaultPrompt(getter_AddRefs(promptObject));
-
   if (!buf)
   {
     nsresult ignoreMe;
     Fail(NS_ERROR_OUT_OF_MEMORY, nullptr, &ignoreMe);
     NotifyListenerOnStopSending(nullptr, NS_ERROR_OUT_OF_MEMORY, nullptr, nullptr);
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
@@ -3388,19 +3383,16 @@ nsMsgComposeAndSend::DeliverFileAsNews()
 {
   nsresult rv = NS_OK;
   if (!(mCompFields->GetNewsgroups()))
     return rv;
 
   if (mSendReport)
     mSendReport->SetCurrentProcess(nsIMsgSendReport::process_NNTP);
 
-  nsCOMPtr<nsIPrompt> promptObject;
-  GetDefaultPrompt(getter_AddRefs(promptObject));
-
   nsCOMPtr<nsINntpService> nntpService(do_GetService(NS_NNTPSERVICE_CONTRACTID, &rv));
 
   if (NS_SUCCEEDED(rv) && nntpService)
   {
     MsgDeliveryListener *deliveryListener = new MsgDeliveryListener(this, true);
     if (!deliveryListener)
       return NS_ERROR_OUT_OF_MEMORY;
 
@@ -3433,17 +3425,18 @@ nsMsgComposeAndSend::Fail(nsresult aFail
                           nsresult *aResult)
 {
   NS_ENSURE_ARG_POINTER(aResult);
   *aResult = aFailureCode;
 
   if (NS_FAILED(aFailureCode))
   {
     nsCOMPtr<nsIPrompt> prompt;
-    GetDefaultPrompt(getter_AddRefs(prompt));
+    nsresult rv = GetDefaultPrompt(getter_AddRefs(prompt));
+    NS_ENSURE_SUCCESS(rv, rv);
 
     if (mSendReport)
     {
       int32_t process;
       if (NS_SUCCEEDED(mSendReport->GetCurrentProcess(&process)) && process == nsIMsgSendReport::process_Current)
       {
         // currentProcess isn't set yet, so we need another value.
         mSendReport->SetCurrentProcess(nsIMsgSendReport::process_BuildMessage);
@@ -3783,21 +3776,21 @@ nsMsgComposeAndSend::NotifyListenerOnSto
   nsString msg;
   if (NS_SUCCEEDED(aStatus))
     mComposeBundle->GetStringFromName("copyMessageComplete", msg);
   else
     mComposeBundle->GetStringFromName("copyMessageFailed", msg);
 
   SetStatusMessage(msg);
   nsCOMPtr<nsIPrompt> prompt;
-  GetDefaultPrompt(getter_AddRefs(prompt));
+  nsresult rv = GetDefaultPrompt(getter_AddRefs(prompt));
+  NS_ENSURE_SUCCESS(rv, rv);
 
   if (NS_FAILED(aStatus))
   {
-    nsresult rv;
     nsCOMPtr<nsIStringBundleService> bundleService =
       mozilla::services::GetStringBundleService();
     NS_ENSURE_TRUE(bundleService, NS_ERROR_UNEXPECTED);
     nsCOMPtr<nsIStringBundle> bundle;
     rv = bundleService->CreateBundle("chrome://messenger/locale/messengercompose/composeMsgs.properties", getter_AddRefs(bundle));
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Obtain account name for local folders.
@@ -3893,33 +3886,34 @@ nsMsgComposeAndSend::NotifyListenerOnSto
                      mCompFields->GetBcc(),
                      nullptr,
                      mCompFields->GetNewspostUrl());
 
       if (NS_FAILED(rv))
       {
         // Save to Local Folders failed. Inform the user.
         nsCOMPtr<nsIPrompt> prompt;
-        GetDefaultPrompt(getter_AddRefs(prompt));
+        rv = GetDefaultPrompt(getter_AddRefs(prompt));
+        NS_ENSURE_SUCCESS(rv, rv);
         nsMsgDisplayMessageByName(prompt, "saveToLocalFoldersFailed");
       }
     }
 
     // Failure detected when user saved to default folder and the user did not
     // retry; instead the user saved to Local Folders or canceled the save. So
     // just call Fail() with a success code so that it doesn't prompt the user
     // again since the user already knows about the failure and has reacted.
     Fail(NS_OK, nullptr, &aStatus);
   }
 
   if (NS_SUCCEEDED(aStatus) &&
       !mPerformingSecondFCC && m_messageKey != nsMsgKey_None &&
       (m_deliver_mode == nsMsgDeliverNow || m_deliver_mode == nsMsgSendUnsent))
   {
-    nsresult rv = FilterSentMessage();
+    rv = FilterSentMessage();
     if (NS_FAILED(rv))
       OnStopOperation(rv);
     return rv;
   }
 
   return MaybePerformSecondFCC(aStatus);
 }
 
@@ -3971,17 +3965,18 @@ nsMsgComposeAndSend::OnStopOperation(nsr
   SetStatusMessage(msg);
 
   if (NS_FAILED(aStatus))
   {
     nsresult rv = mComposeBundle->GetStringFromName("errorFilteringMsg", msg);
     if (NS_SUCCEEDED(rv))
     {
       nsCOMPtr<nsIPrompt> prompt;
-      GetDefaultPrompt(getter_AddRefs(prompt));
+      rv = GetDefaultPrompt(getter_AddRefs(prompt));
+      NS_ENSURE_SUCCESS(rv, rv);
       nsMsgDisplayMessageByString(prompt, msg.get(), nullptr);
     }
 
     // We failed, however, give Fail a success code so that it doesn't prompt
     // the user a second time as they already know about the failure.
     Fail(NS_OK, nullptr, &aStatus);
   }