[tor-commits] [tor-browser/tor-browser-52.1.1esr-7.0-1] fixup! Bug 19273: Avoid JavaScript patching of the external app helper dialog.

gk at torproject.org gk at torproject.org
Mon May 22 07:57:16 UTC 2017


commit 4a4285cbd06a825e5f2277d12a2e5165eab59837
Author: Kathy Brade <brade at pearlcrescent.com>
Date:   Fri May 19 11:25:31 2017 -0400

    fixup! Bug 19273: Avoid JavaScript patching of the external app helper dialog.
    
    For e10s compatibility, send the "external-app-requested" observer
    notification later in the download process, and suspend active requests
    while doing so. Fixes bug 21766.
    
    This change also fixes a problem in the esr52-based browser where
    downloads stalled when e10s was disabled. Fixes bug 21886.
---
 netwerk/protocol/http/HttpBaseChannel.cpp          |  7 ++++
 netwerk/protocol/http/HttpBaseChannel.h            |  1 +
 netwerk/protocol/http/NullHttpChannel.cpp          |  6 ++++
 netwerk/protocol/http/nsIHttpChannel.idl           |  9 ++++-
 .../protocol/viewsource/nsViewSourceChannel.cpp    | 11 ++++++
 .../exthandler/nsExternalHelperAppService.cpp      | 41 +++++++++++++++++-----
 6 files changed, 66 insertions(+), 9 deletions(-)

diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp
index e0f7ede..5ea6a00 100644
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -1233,6 +1233,13 @@ NS_IMETHODIMP HttpBaseChannel::SetTopLevelContentWindowId(uint64_t aWindowId)
   return NS_OK;
 }
 
+NS_IMETHODIMP HttpBaseChannel::IsPendingUnforced(bool *aIsPendingUnforced)
+{
+  NS_ENSURE_ARG_POINTER(aIsPendingUnforced);
+  *aIsPendingUnforced = mIsPending;
+  return NS_OK;
+}
+
 NS_IMETHODIMP
 HttpBaseChannel::GetTransferSize(uint64_t *aTransferSize)
 {
diff --git a/netwerk/protocol/http/HttpBaseChannel.h b/netwerk/protocol/http/HttpBaseChannel.h
index c8184a6..3a1a8ba 100644
--- a/netwerk/protocol/http/HttpBaseChannel.h
+++ b/netwerk/protocol/http/HttpBaseChannel.h
@@ -190,6 +190,7 @@ public:
   NS_IMETHOD SetChannelId(const nsACString& aChannelId) override;
   NS_IMETHOD GetTopLevelContentWindowId(uint64_t *aContentWindowId) override;
   NS_IMETHOD SetTopLevelContentWindowId(uint64_t aContentWindowId) override;
+  NS_IMETHOD IsPendingUnforced(bool *aIsPendingUnforced) override;
 
   // nsIHttpChannelInternal
   NS_IMETHOD GetDocumentURI(nsIURI **aDocumentURI) override;
diff --git a/netwerk/protocol/http/NullHttpChannel.cpp b/netwerk/protocol/http/NullHttpChannel.cpp
index 8c048a6..8b362cb 100644
--- a/netwerk/protocol/http/NullHttpChannel.cpp
+++ b/netwerk/protocol/http/NullHttpChannel.cpp
@@ -82,6 +82,12 @@ NullHttpChannel::SetTopLevelContentWindowId(uint64_t aWindowId)
 }
 
 NS_IMETHODIMP
+NullHttpChannel::IsPendingUnforced(bool *_retval)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
 NullHttpChannel::GetTransferSize(uint64_t *aTransferSize)
 {
     return NS_ERROR_NOT_IMPLEMENTED;
diff --git a/netwerk/protocol/http/nsIHttpChannel.idl b/netwerk/protocol/http/nsIHttpChannel.idl
index 75ec2c7..0de0676 100644
--- a/netwerk/protocol/http/nsIHttpChannel.idl
+++ b/netwerk/protocol/http/nsIHttpChannel.idl
@@ -14,7 +14,7 @@ interface nsIHttpHeaderVisitor;
  * the inspection of the resulting HTTP response status and headers when they
  * become available.
  */
-[builtinclass, scriptable, uuid(c5a4a073-4539-49c7-a3f2-cec3f0619c6c)]
+[builtinclass, scriptable, uuid(e0d8071b-5389-48c2-92c7-6708c968044d)]
 interface nsIHttpChannel : nsIChannel
 {
     /**************************************************************************
@@ -469,4 +469,11 @@ interface nsIHttpChannel : nsIChannel
      * this channels is being load in.
      */
     attribute uint64_t topLevelContentWindowId;
+
+    /**
+     * Returns true if a request is pending due to "natural" causes and
+     * not just because ForcePending() has been called. See isPending()
+     * in nsIRequest.idl for more details about pending requests.
+     */
+    boolean isPendingUnforced();
 };
diff --git a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
index 9ed71c4..9f9b894 100644
--- a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
+++ b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
@@ -740,6 +740,17 @@ nsViewSourceChannel::SetTopLevelContentWindowId(uint64_t aWindowId)
 }
 
 NS_IMETHODIMP
+nsViewSourceChannel::IsPendingUnforced(bool *result)
+{
+  if (mHttpChannel) {
+    return mHttpChannel->IsPendingUnforced(result);
+  }
+
+  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
+  return mChannel->IsPending(result);
+}
+
+NS_IMETHODIMP
 nsViewSourceChannel::GetRequestMethod(nsACString & aRequestMethod)
 {
     return !mHttpChannel ? NS_ERROR_NULL_POINTER :
diff --git a/uriloader/exthandler/nsExternalHelperAppService.cpp b/uriloader/exthandler/nsExternalHelperAppService.cpp
index dfaa218..4c25ae2 100644
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -106,6 +106,7 @@
 
 #include "mozilla/Preferences.h"
 #include "mozilla/ipc/URIUtils.h"
+#include "mozilla/Unused.h"
 
 using namespace mozilla;
 using namespace mozilla::ipc;
@@ -731,14 +732,6 @@ NS_IMETHODIMP nsExternalHelperAppService::DoContent(const nsACString& aMimeConte
                                          aForceSave, aWindowContext, aStreamListener);
   }
 
-  // Give other modules, including extensions, a chance to cancel.
-  bool doCancel = false;
-  nsresult rv = shouldCancel(&doCancel);
-  NS_ENSURE_SUCCESS(rv, rv);
-  if (doCancel) {
-    return NS_ERROR_FAILURE;
-  }
-
   nsAutoString fileName;
   nsAutoCString fileExtension;
   uint32_t reason = nsIHelperAppLauncherDialog::REASON_CANTHANDLE;
@@ -775,6 +768,7 @@ NS_IMETHODIMP nsExternalHelperAppService::DoContent(const nsACString& aMimeConte
         nsAutoCString query;
 
         // We only care about the query for HTTP and HTTPS URLs
+        nsresult rv;
         bool isHTTP, isHTTPS;
         rv = uri->SchemeIs("http", &isHTTP);
         if (NS_FAILED(rv)) {
@@ -1675,6 +1669,37 @@ NS_IMETHODIMP nsExternalAppHandler::OnStartRequest(nsIRequest *request, nsISuppo
     return NS_OK;
   }
 
+  // Give other modules, including extensions, a chance to cancel.
+  // To avoid a problem where OnDataAvailable fires but is not handled
+  // correctly while a modal dialog displayed by Torbutton is open, we
+  // suspend and then we either cancel or resume active requests.
+  // See bugs 21766 and 21886.
+  bool isPending = false;
+  nsCOMPtr<nsIHttpChannel> httpChan = do_QueryInterface(request);
+  if (httpChan) {
+    rv = httpChan->IsPendingUnforced(&isPending);
+  } else {
+    rv = request->IsPending(&isPending);
+  }
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  if (isPending) {
+    Unused << request->Suspend(); // Best effort: ignore failures.
+  }
+
+  bool doCancel = false;
+  rv = shouldCancel(&doCancel);
+  NS_ENSURE_SUCCESS(rv, rv);
+  if (doCancel) {
+    mCanceled = true;
+    request->Cancel(NS_BINDING_ABORTED);
+    return NS_OK;
+  }
+
+  if (isPending) {
+    Unused << request->Resume();  // Best effort: ignore failures.
+  }
+
   rv = SetUpTempFile(aChannel);
   if (NS_FAILED(rv)) {
     nsresult transferError = rv;



More information about the tor-commits mailing list