Commit 9ca6973c authored by Kathleen Brade's avatar Kathleen Brade Committed by Georg Koppen
Browse files

Bug 19273: Avoid JavaScript patching of the external app helper dialog.

Before launching an external application, broadcast an
"external-app-requested" observer service notification to allow
other modules, including extensions, a chance to cancel the launch.
parent 0f9c1d2b
Loading
Loading
Loading
Loading
+33 −1
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@
#include "nsThreadUtils.h"
#include "nsAutoPtr.h"
#include "nsIMutableArray.h"
#include "nsISupportsPrimitives.h" // for nsISupportsPRBool

// used to access our datastore of user-configured helper applications
#include "nsIHandlerService.h"
@@ -480,6 +481,22 @@ static nsresult GetDownloadDirectory(nsIFile **_directory,
  return NS_OK;
}

static nsresult shouldCancel(bool *aShouldCancel)
{
  NS_ENSURE_ARG_POINTER(aShouldCancel);

  nsCOMPtr<nsISupportsPRBool> cancelObj =
                            do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID);
  cancelObj->SetData(false);
  nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
  if (!obs)
    return NS_ERROR_FAILURE;

  obs->NotifyObservers(cancelObj, "external-app-requested", nullptr);
  cancelObj->GetData(aShouldCancel);
  return NS_OK;
}

/**
 * Structure for storing extension->type mappings.
 * @see defaultMimeEntries
@@ -762,6 +779,14 @@ 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;
@@ -798,7 +823,6 @@ 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)) {
@@ -1058,6 +1082,14 @@ nsExternalHelperAppService::LoadURI(nsIURI *aURI,
    return NS_OK; // explicitly denied
  }

  // Give other modules, including extensions, a chance to cancel.
  bool doCancel = false;
  rv = shouldCancel(&doCancel);
  NS_ENSURE_SUCCESS(rv, rv);
  if (doCancel) {
    return NS_OK;
  }

  nsCOMPtr<nsIHandlerInfo> handler;
  rv = GetProtocolHandlerInfo(scheme, getter_AddRefs(handler));
  NS_ENSURE_SUCCESS(rv, rv);