Commit 96325541 authored by Gijs Kruitbosch's avatar Gijs Kruitbosch
Browse files

Bug 1606300 - escape filenames in tab titles, save as... dialog and as used by...

Bug 1606300 - escape filenames in tab titles, save as... dialog and as used by webbrowserpersist, r=valentin

The getDefaultFileName helper function does its own filename parsing using header info
it has previously 'manually' retrieved, so it needs to manually unescape its input.

Meanwhile, NS_GetFilenameFromDisposition is used by webbrowserpersist and for
the title of documents, and so updating that helps ensure better UI as well as
correct filename suggestions when saving from the context menu.

Differential Revision: https://phabricator.services.mozilla.com/D61734

--HG--
rename : accessible/tests/mochitest/moz.png => uriloader/exthandler/tests/mochitest/file_with@@funny_name.png
rename : toolkit/components/mediasniffer/test/unit/data/file.webm => uriloader/exthandler/tests/mochitest/file_with[funny_name.webm
extra : moz-landing-system : lando
parent 04ffe075
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@
#include "nsIIncrementalStreamLoader.h"
#include "nsStringStream.h"
#include "nsSyncStreamListener.h"
#include "nsITextToSubURI.h"
#include "nsIURIWithSpecialOrigin.h"
#include "nsIViewSourceChannel.h"
#include "nsInterfaceRequestorAgg.h"
@@ -2674,6 +2675,19 @@ nsresult NS_GetFilenameFromDisposition(nsAString& aFilename,

  if (aFilename.IsEmpty()) return NS_ERROR_NOT_AVAILABLE;

  // Filename may still be percent-encoded. Fix:
  if (aFilename.FindChar('%') != -1) {
    nsCOMPtr<nsITextToSubURI> textToSubURI =
        do_GetService(NS_ITEXTTOSUBURI_CONTRACTID, &rv);
    if (NS_SUCCEEDED(rv)) {
      nsAutoString unescaped;
      textToSubURI->UnEscapeURIForUI(NS_LITERAL_CSTRING("UTF-8"),
                                     NS_ConvertUTF16toUTF8(aFilename),
                                     unescaped);
      aFilename.Assign(unescaped);
    }
  }

  return NS_OK;
}

+3 −1
Original line number Diff line number Diff line
@@ -1197,7 +1197,9 @@ function getDefaultFileName(
      } catch (e) {}
    }
    if (fileName) {
      return validateFileName(fileName);
      return validateFileName(
        Services.textToSubURI.unEscapeURIForUI("UTF-8", fileName)
      );
    }
  }

+6 −0
Original line number Diff line number Diff line
@@ -11,6 +11,12 @@ support-files =
  download.sjs
[browser_download_always_ask_preferred_app.js]
[browser_download_privatebrowsing.js]
[browser_download_urlescape.js]
support-files =
  file_with@@funny_name.png
  file_with@@funny_name.png^headers^
  file_with[funny_name.webm
  file_with[funny_name.webm^headers^
[browser_protocolhandler_loop.js]
skip-if = fission # Bug 1597154
[browser_remember_download_option.js]
+75 −0
Original line number Diff line number Diff line
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

const TEST_PATH = getRootDirectory(gTestPath).replace(
  "chrome://mochitests/content",
  "https://example.com"
);

var MockFilePicker = SpecialPowers.MockFilePicker;
MockFilePicker.init(window);
registerCleanupFunction(() => MockFilePicker.cleanup());

/**
 * Check downloading files URL-escapes content-disposition
 * information when necessary.
 */
add_task(async function test_check_filename_urlescape() {
  let pendingPromise;
  let pendingTest = "";
  let expectedFileName = "";
  MockFilePicker.showCallback = function(fp) {
    info(`${pendingTest} - Filepicker shown, checking filename`);
    is(
      fp.defaultString,
      expectedFileName,
      `${pendingTest} - Should have escaped filename`
    );
    ok(
      pendingPromise,
      `${pendingTest} - Should have expected this picker open.`
    );
    if (pendingPromise) {
      pendingPromise.resolve();
    }
    return Ci.nsIFilePicker.returnCancel;
  };
  function runTestFor(fileName, selector) {
    return BrowserTestUtils.withNewTab(TEST_PATH + fileName, async browser => {
      expectedFileName = fileName;
      let tabLabel = gBrowser.getTabForBrowser(browser).getAttribute("label");
      ok(
        tabLabel.startsWith(fileName),
        `"${tabLabel}" should have been escaped.`
      );

      pendingTest = "save browser";
      pendingPromise = PromiseUtils.defer();
      // First try to save the browser
      saveBrowser(browser);
      await pendingPromise.promise;

      // Next, try the context menu:
      pendingTest = "save from context menu";
      pendingPromise = PromiseUtils.defer();
      let menu = document.getElementById("contentAreaContextMenu");
      let menuShown = BrowserTestUtils.waitForEvent(menu, "popupshown");
      BrowserTestUtils.synthesizeMouse(
        selector,
        5,
        5,
        { type: "contextmenu", button: 2 },
        browser
      );
      await menuShown;
      gContextMenu.saveMedia();
      menu.hidePopup();
      await pendingPromise.promise;
      pendingPromise = null;
    });
  }
  await runTestFor("file_with@@funny_name.png", "img");
  await runTestFor("file_with[funny_name.webm", "video");
});
+1.94 KiB
Loading image diff...
Loading