[tbb-commits] [tor-browser] 37/46: Bug 1778597, append valid extensions only when saving a page, r=Gijs, necko-reviewers, a=dmeehan

gitolite role git at cupani.torproject.org
Wed Nov 16 20:43:17 UTC 2022


This is an automated email from the git hooks/post-receive script.

richard pushed a commit to branch base-browser-102.5.0esr-12.0-1
in repository tor-browser.

commit 2bf1348368a4b40e70c14a59f420ef5780597ee5
Author: Neil Deakin <neil at mozilla.com>
AuthorDate: Wed Oct 19 12:50:16 2022 +0000

    Bug 1778597, append valid extensions only when saving a page, r=Gijs,necko-reviewers, a=dmeehan
    
    Differential Revision: https://phabricator.services.mozilla.com/D159478
---
 netwerk/mime/nsIMIMEService.idl                    | 10 +++++++
 toolkit/content/contentAreaUtils.js                |  2 +-
 .../exthandler/nsExternalHelperAppService.cpp      |  8 +++--
 uriloader/exthandler/nsExternalHelperAppService.h  |  1 +
 .../tests/mochitest/browser_save_filenames.js      | 35 +++++++++++++++++++++-
 .../exthandler/tests/mochitest/save_filenames.html | 11 ++++---
 6 files changed, 58 insertions(+), 9 deletions(-)

diff --git a/netwerk/mime/nsIMIMEService.idl b/netwerk/mime/nsIMIMEService.idl
index c5d1efbd7575..2931ea0cdc51 100644
--- a/netwerk/mime/nsIMIMEService.idl
+++ b/netwerk/mime/nsIMIMEService.idl
@@ -149,6 +149,16 @@ interface nsIMIMEService : nsISupports {
      */
     const long VALIDATE_NO_DEFAULT_FILENAME = 32;
 
+    /**
+     * When the filename has an invalid extension, force the the filename to
+     * have a valid extension appended to the end of the filename when that
+     * extension would normally be ignored for the given content type. This
+     * primarily is used when saving pages to ensure that the html extension
+     * is applied over any extension that might have been generated from a
+     * page title.
+     */
+    const long VALIDATE_FORCE_APPEND_EXTENSION = 64;
+
     /**
      * Generate a valid filename from the channel that can be used to save
      * the content of the channel to the local disk.
diff --git a/toolkit/content/contentAreaUtils.js b/toolkit/content/contentAreaUtils.js
index 68905b0a8e8d..88dced3ac890 100644
--- a/toolkit/content/contentAreaUtils.js
+++ b/toolkit/content/contentAreaUtils.js
@@ -600,7 +600,7 @@ function initFileInfo(
     aFI.fileName = mimeService.validateFileNameForSaving(
       fileName,
       aContentType,
-      mimeService.VALIDATE_DEFAULT
+      mimeService.VALIDATE_FORCE_APPEND_EXTENSION
     );
 
     // If uriExt is blank, consider: aFI.suggestedFileName is supplied if
diff --git a/uriloader/exthandler/nsExternalHelperAppService.cpp b/uriloader/exthandler/nsExternalHelperAppService.cpp
index 0fdfe1936a4e..0cfe522d2942 100644
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -3433,8 +3433,9 @@ nsExternalHelperAppService::ValidateFileNameForSaving(
         // If an suitable extension was found, we will append to or replace the
         // existing extension.
         if (!extension.IsEmpty()) {
-          ModifyExtensionType modify =
-              ShouldModifyExtension(mimeInfo, originalExtension);
+          ModifyExtensionType modify = ShouldModifyExtension(
+              mimeInfo, aFlags & VALIDATE_FORCE_APPEND_EXTENSION,
+              originalExtension);
           if (modify == ModifyExtension_Replace) {
             int32_t dotidx = fileName.RFind(".");
             if (dotidx != -1) {
@@ -3685,6 +3686,7 @@ void nsExternalHelperAppService::SanitizeFileName(nsAString& aFileName,
 
 nsExternalHelperAppService::ModifyExtensionType
 nsExternalHelperAppService::ShouldModifyExtension(nsIMIMEInfo* aMimeInfo,
+                                                  bool aForceAppend,
                                                   const nsCString& aFileExt) {
   nsAutoCString MIMEType;
   if (!aMimeInfo || NS_FAILED(aMimeInfo->GetMIMEType(MIMEType))) {
@@ -3709,7 +3711,7 @@ nsExternalHelperAppService::ShouldModifyExtension(nsIMIMEInfo* aMimeInfo,
     }
 
     if (!canForce) {
-      return ModifyExtension_Ignore;
+      return aForceAppend ? ModifyExtension_Append : ModifyExtension_Ignore;
     }
   }
 
diff --git a/uriloader/exthandler/nsExternalHelperAppService.h b/uriloader/exthandler/nsExternalHelperAppService.h
index 439be1645f4f..1374d74255b3 100644
--- a/uriloader/exthandler/nsExternalHelperAppService.h
+++ b/uriloader/exthandler/nsExternalHelperAppService.h
@@ -226,6 +226,7 @@ class nsExternalHelperAppService : public nsIExternalHelperAppService,
     ModifyExtension_Ignore = 2
   };
   ModifyExtensionType ShouldModifyExtension(nsIMIMEInfo* aMimeInfo,
+                                            bool aForceAppend,
                                             const nsCString& aFileExt);
 
   /**
diff --git a/uriloader/exthandler/tests/mochitest/browser_save_filenames.js b/uriloader/exthandler/tests/mochitest/browser_save_filenames.js
index af4bf421dfe5..7b0f3c6747bc 100644
--- a/uriloader/exthandler/tests/mochitest/browser_save_filenames.js
+++ b/uriloader/exthandler/tests/mochitest/browser_save_filenames.js
@@ -13,6 +13,7 @@ requestLongerTimeout(8);
 
 let types = {
   text: "text/plain",
+  html: "text/html",
   png: "image/png",
   jpeg: "image/jpeg",
   webp: "image/webp",
@@ -93,6 +94,10 @@ function handleRequest(aRequest, aResponse) {
     aResponse.write(JPEG_DATA);
   } else if (type == "webp") {
     aResponse.write(WEBP_DATA);
+  } else if (type == "html") {
+    aResponse.write(
+      "<html><head><title>file.inv</title></head><body>File</body></html>"
+    );
   } else {
     aResponse.write("// Some Text");
   }
@@ -202,12 +207,14 @@ function getItems(parentid) {
           elem.localName == "img" && elem.dataset.nodrag != "true";
         let unknown = elem.dataset.unknown;
         let noattach = elem.dataset.noattach;
+        let savepagename = elem.dataset.savepagename;
         elements.push({
           draggable,
           unknown,
           filename,
           url,
           noattach,
+          savepagename,
         });
         elem = elem.nextElementSibling;
       }
@@ -508,7 +515,7 @@ add_task(async function saveas_files() {
       // filename index.html.
       let expectedFilename = expectedItems[idx].unknown
         ? DEFAULT_INDEX_FILENAME
-        : expectedItems[idx].filename;
+        : expectedItems[idx].savepagename || expectedItems[idx].filename;
 
       // When saving via contentAreaUtils.js, the content disposition name
       // field is used as an alternate.
@@ -739,6 +746,32 @@ add_task(async function save_download_links() {
   }
 });
 
+add_task(async function save_page_with_invalid_extension() {
+  await BrowserTestUtils.openNewForegroundTab(
+    gBrowser,
+    "http://localhost:8000/save_filename.sjs?type=html"
+  );
+
+  let filename = await new Promise(resolve => {
+    MockFilePicker.showCallback = function(fp) {
+      setTimeout(() => {
+        resolve(fp.defaultString);
+      }, 0);
+      return Ci.nsIFilePicker.returnCancel;
+    };
+
+    document.getElementById("Browser:SavePage").doCommand();
+  });
+
+  is(
+    filename,
+    AppConstants.platform == "win" ? "file.inv.htm" : "file.inv.html",
+    "html extension has been added"
+  );
+
+  await BrowserTestUtils.removeTab(gBrowser.selectedTab);
+});
+
 add_task(async () => {
   BrowserTestUtils.removeTab(gBrowser.selectedTab);
   MockFilePicker.cleanup();
diff --git a/uriloader/exthandler/tests/mochitest/save_filenames.html b/uriloader/exthandler/tests/mochitest/save_filenames.html
index 0d7004515a9b..366e21dab277 100644
--- a/uriloader/exthandler/tests/mochitest/save_filenames.html
+++ b/uriloader/exthandler/tests/mochitest/save_filenames.html
@@ -88,11 +88,11 @@
 
 <!-- script with invalid extension. -->
 <script id="i23" src="http://localhost:8000/save_filename.sjs?type=js&filename=script2.exe"
-        data-filename="script2.exe"></script>
+        data-filename="script2.exe" data-savepagename="script2.exe.js"></script>
 
 <!-- script with escaped characters -->
 <script id="i24" src="http://localhost:8000/save_filename.sjs?type=js&filename=script%20%33.exe"
-        data-filename="script 3.exe"></script>
+        data-filename="script 3.exe" data-savepagename="script 3.exe.js"></script>
 
 <!-- script with long filename -->
 <script id="i25" src="http://localhost:8000/save_filename.sjs?type=js&filename=script123456789script123456789script123456789script123456789script123456789script123456789script123456789script123456789script123456789script123456789script123456789script123456789script123456789script123456789script123456789script123456789script123456789script123456789.js"
@@ -152,11 +152,11 @@
 
 <!-- script where url filename has no extension and invalid extension in content disposition filename -->
 <script id="i41" src="http://localhost:8000/base?type=js&filename=script5.exe"
-        data-filename="script5.exe"></script>
+        data-filename="script5.exe" data-savepagename="script5.exe.js"></script>
 
 <!-- script where url filename has no extension and escaped characters in content disposition filename-->
 <script id="i42" src="http://localhost:8000/base?type=js&filename=script%20%36.exe"
-        data-filename="script 6.exe"></script>
+        data-filename="script 6.exe" data-savepagename="script 6.exe.js"></script>
 
 <!-- text where filename is present -->
 <img id="i43" src="http://localhost:8000/getdata.png?type=text&filename=readme.txt"
@@ -292,6 +292,9 @@
 <img id="i76" src="http://localhost:8000/executable.exe?type=gook"
      data-nodrag="true" data-unknown="typeonly" data-filename="executable.exe">
 
+<!-- embedded child html -->
+<object id="i77" data="http://localhost:8000/save_filename.sjs?type=html&filename=child.par"
+        data-filename="child.par" data-unknown="true"></object>
 </span>
 
 <!-- This set is used to test the filename specified by the download attribute is validated correctly. -->

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the tbb-commits mailing list