Bug 1610406 - Make nsMsgWindow::GetMessageWindowDocShell() fail if docshell is being destroyed. r=mkmelin a=wsmwk
authorBen Campbell <benc@thunderbird.net>
Mon, 24 Feb 2020 11:56:08 +0200
changeset 38181 3cfca362ac8cb85053b45811a2bda1e7dd333252
parent 38180 75481e886915fdb1299f4ff0437dd21f79ec44e6
child 38182 181293f406d7683dd257aba18d32a89528fca0eb
push id398
push userclokep@gmail.com
push dateMon, 09 Mar 2020 19:10:28 +0000
reviewersmkmelin, wsmwk
bugs1610406
Bug 1610406 - Make nsMsgWindow::GetMessageWindowDocShell() fail if docshell is being destroyed. r=mkmelin a=wsmwk
mailnews/base/src/nsMsgWindow.cpp
mailnews/imap/src/nsImapProtocol.cpp
--- a/mailnews/base/src/nsMsgWindow.cpp
+++ b/mailnews/base/src/nsMsgWindow.cpp
@@ -67,16 +67,25 @@ nsresult nsMsgWindow::Init() {
 NS_IMETHODIMP nsMsgWindow::GetMessageWindowDocShell(nsIDocShell **aDocShell) {
   *aDocShell = nullptr;
   nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mMessageWindowDocShellWeak));
   if (!docShell) {
     // if we don't have a docshell, then we need to look up the message pane
     // docshell
     nsCOMPtr<nsIDocShell> rootShell(do_QueryReferent(mRootDocShellWeak));
     if (rootShell) {
+      // There seem to be some issues with shutdown (see Bug 1610406).
+      // This workaround should prevent the GetElementById() call dying horribly
+      // but really, we shouldn't even get here in such cases.
+      bool doomed;
+      rootShell->IsBeingDestroyed(&doomed);
+      if (doomed) {
+        return NS_ERROR_ILLEGAL_DURING_SHUTDOWN;
+      }
+
       RefPtr<mozilla::dom::Element> el =
           rootShell->GetDocument()->GetElementById(
               NS_LITERAL_STRING("messagepane"));
       RefPtr<mozilla::dom::XULFrameElement> frame =
           mozilla::dom::XULFrameElement::FromNodeOrNull(el);
       NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
       RefPtr<mozilla::dom::Document> doc = frame->GetContentDocument();
       NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
--- a/mailnews/imap/src/nsImapProtocol.cpp
+++ b/mailnews/imap/src/nsImapProtocol.cpp
@@ -816,16 +816,19 @@ nsresult nsImapProtocol::SetupWithUrl(ns
       m_mockChannel->GetChannelListener(getter_AddRefs(channelListener));
       if (channelListener)  // only over-ride if we have a non null channel
                             // listener
         aRealStreamListener = channelListener;
       nsCOMPtr<nsIMsgWindow> msgWindow;
       GetMsgWindow(getter_AddRefs(msgWindow));
       if (!msgWindow) GetTopmostMsgWindow(getter_AddRefs(msgWindow));
       if (msgWindow) {
+        // Set up the MockChannel to attempt nsIProgressEventSink callbacks on
+        // the messageWindow, with fallback to the docShell (and the
+        // loadgroup).
         nsCOMPtr<nsIDocShell> docShell;
         msgWindow->GetMessageWindowDocShell(getter_AddRefs(docShell));
         nsCOMPtr<nsIInterfaceRequestor> ir(do_QueryInterface(docShell));
         nsCOMPtr<nsIInterfaceRequestor> interfaceRequestor;
         msgWindow->GetNotificationCallbacks(getter_AddRefs(interfaceRequestor));
         nsCOMPtr<nsIInterfaceRequestor> aggregateIR;
         MsgNewInterfaceRequestorAggregation(interfaceRequestor, ir,
                                             getter_AddRefs(aggregateIR));
@@ -7983,16 +7986,17 @@ void nsImapProtocol::Check() {
     m_flagChangeCount = 0;
     m_lastCheckTime = PR_Now();
     ParseIMAPandCheckForNewMail();
   }
 }
 
 nsresult nsImapProtocol::GetMsgWindow(nsIMsgWindow **aMsgWindow) {
   nsresult rv;
+  *aMsgWindow = nullptr;
   nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl =
       do_QueryInterface(m_runningUrl, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
   if (!m_imapProtocolSink) return NS_ERROR_FAILURE;
   return m_imapProtocolSink->GetUrlWindow(mailnewsUrl, aMsgWindow);
 }
 
 /**