Bug 1433958 - Change code that sets nsIURI.filePath to use nsIURIMutator draft
authorValentin Gosu <valentin.gosu@gmail.com>
Mon, 26 Feb 2018 20:43:45 +0100
changeset 759887 d614710eba7885a93bb9c8740ea2f967adf2c710
parent 759886 1ce650cd2baa2ca3c2e233b49de73c32eb93b617
child 759888 2383863d6341d78cd38b67b7fdc491c2dd24f20a
push id100504
push uservalentin.gosu@gmail.com
push dateMon, 26 Feb 2018 19:44:44 +0000
bugs1433958
milestone60.0a1
Bug 1433958 - Change code that sets nsIURI.filePath to use nsIURIMutator MozReview-Commit-ID: GYHpakKPEbe
dom/base/Link.cpp
dom/base/Location.cpp
dom/url/URLMainThread.cpp
modules/libjar/nsJARURI.cpp
netwerk/protocol/ftp/nsFtpConnectionThread.cpp
netwerk/test/unit/test_standardurl.js
toolkit/content/contentAreaUtils.js
--- a/dom/base/Link.cpp
+++ b/dom/base/Link.cpp
@@ -501,24 +501,29 @@ Link::SetHostname(const nsAString &aHost
 
   (void)uri->SetHost(NS_ConvertUTF16toUTF8(aHostname));
   SetHrefAttribute(uri);
 }
 
 void
 Link::SetPathname(const nsAString &aPathname)
 {
-  nsCOMPtr<nsIURI> uri(GetURIToMutate());
+  nsCOMPtr<nsIURI> uri(GetURI());
   nsCOMPtr<nsIURL> url(do_QueryInterface(uri));
   if (!url) {
     // Ignore failures to be compatible with NS4.
     return;
   }
 
-  (void)url->SetFilePath(NS_ConvertUTF16toUTF8(aPathname));
+  nsresult rv = NS_MutateURI(uri)
+                  .SetFilePath(NS_ConvertUTF16toUTF8(aPathname))
+                  .Finalize(uri);
+  if (NS_FAILED(rv)) {
+    return;
+  }
   SetHrefAttribute(uri);
 }
 
 void
 Link::SetSearch(const nsAString& aSearch)
 {
   nsCOMPtr<nsIURI> uri(GetURIToMutate());
   nsCOMPtr<nsIURL> url(do_QueryInterface(uri));
--- a/dom/base/Location.cpp
+++ b/dom/base/Location.cpp
@@ -595,24 +595,29 @@ Location::SetPathname(const nsAString& a
                       ErrorResult& aRv)
 {
   if (!CallerSubsumes(&aSubjectPrincipal)) {
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return;
   }
 
   nsCOMPtr<nsIURI> uri;
-  aRv = GetWritableURI(getter_AddRefs(uri));
+  aRv = GetURI(getter_AddRefs(uri));
   if (NS_WARN_IF(aRv.Failed()) || !uri) {
     return;
   }
 
-  if (NS_SUCCEEDED(uri->SetFilePath(NS_ConvertUTF16toUTF8(aPathname)))) {
-    aRv = SetURI(uri);
+  nsresult rv = NS_MutateURI(uri)
+                  .SetFilePath(NS_ConvertUTF16toUTF8(aPathname))
+                  .Finalize(uri);
+  if (NS_FAILED(rv)) {
+    return;
   }
+
+  aRv = SetURI(uri);
 }
 
 void
 Location::GetPort(nsAString& aPort,
                   nsIPrincipal& aSubjectPrincipal,
                   ErrorResult& aRv)
 {
   if (!CallerSubsumes(&aSubjectPrincipal)) {
--- a/dom/url/URLMainThread.cpp
+++ b/dom/url/URLMainThread.cpp
@@ -399,17 +399,19 @@ URLMainThread::GetPathname(nsAString& aP
   }
 }
 
 void
 URLMainThread::SetPathname(const nsAString& aPathname, ErrorResult& aRv)
 {
   // Do not throw!
 
-  mURI->SetFilePath(NS_ConvertUTF16toUTF8(aPathname));
+  Unused << NS_MutateURI(mURI)
+              .SetFilePath(NS_ConvertUTF16toUTF8(aPathname))
+              .Finalize(mURI);
 }
 
 void
 URLMainThread::GetSearch(nsAString& aSearch, ErrorResult& aRv) const
 {
   aSearch.Truncate();
 
   // Do not throw!  Not having a valid URI or URL should result in an empty
--- a/modules/libjar/nsJARURI.cpp
+++ b/modules/libjar/nsJARURI.cpp
@@ -659,17 +659,19 @@ NS_IMETHODIMP
 nsJARURI::GetFilePath(nsACString& filePath)
 {
     return mJAREntry->GetFilePath(filePath);
 }
 
 NS_IMETHODIMP
 nsJARURI::SetFilePath(const nsACString& filePath)
 {
-    return mJAREntry->SetFilePath(filePath);
+    return NS_MutateURI(mJAREntry)
+             .SetFilePath(filePath)
+             .Finalize(mJAREntry);
 }
 
 NS_IMETHODIMP
 nsJARURI::GetQuery(nsACString& query)
 {
     return mJAREntry->GetQuery(query);
 }
 
--- a/netwerk/protocol/ftp/nsFtpConnectionThread.cpp
+++ b/netwerk/protocol/ftp/nsFtpConnectionThread.cpp
@@ -1142,17 +1142,22 @@ nsFtpState::SetContentType()
     // (e.g. LIST command processing) so that it ensures the terminating
     // slash is appended for the new request case.
 
     if (!mPath.IsEmpty() && mPath.Last() != '/') {
         nsCOMPtr<nsIURL> url = (do_QueryInterface(mChannel->URI()));
         nsAutoCString filePath;
         if(NS_SUCCEEDED(url->GetFilePath(filePath))) {
             filePath.Append('/');
-            url->SetFilePath(filePath);
+            nsresult rv = NS_MutateURI(url)
+                            .SetFilePath(filePath)
+                            .Finalize(url);
+            if (NS_SUCCEEDED(rv)) {
+                mChannel->UpdateURI(url);
+            }
         }
     }
     return mChannel->SetContentType(
         NS_LITERAL_CSTRING(APPLICATION_HTTP_INDEX_FORMAT));
 }
 
 nsresult
 nsFtpState::S_list() {
--- a/netwerk/test/unit/test_standardurl.js
+++ b/netwerk/test/unit/test_standardurl.js
@@ -298,25 +298,26 @@ add_test(function test_hugeStringThrows(
   let prefs = Cc["@mozilla.org/preferences-service;1"]
                 .getService(Ci.nsIPrefService);
   let maxLen = prefs.getIntPref("network.standard-url.max-length");
   let url = stringToURL("http://test:test@example.com");
 
   let hugeString = new Array(maxLen + 1).fill("a").join("");
   let properties = ["scheme", "userPass", "username",
                     "password", "host", "ref",
-                    "query", "filePath"];
+                    "query"];
   for (let prop of properties) {
     Assert.throws(() => url[prop] = hugeString,
                   /NS_ERROR_MALFORMED_URI/,
                   `Passing a huge string to "${prop}" should throw`);
   }
 
   let setters = [
     { method: "setSpec", qi: Ci.nsIURIMutator },
+    { method: "setFilePath", qi: Ci.nsIURIMutator },
     { method: "setHostPort", qi: Ci.nsIURIMutator },
     { method: "setPathQueryRef", qi: Ci.nsIURIMutator },
     { method: "setFileName", qi: Ci.nsIURLMutator },
     { method: "setFileExtension", qi: Ci.nsIURLMutator },
     { method: "setFileBaseName", qi: Ci.nsIURLMutator },
   ];
 
   for (let prop of setters) {
@@ -330,17 +331,17 @@ add_test(function test_hugeStringThrows(
 
 add_test(function test_filterWhitespace()
 {
   var url = stringToURL(" \r\n\th\nt\rt\tp://ex\r\n\tample.com/path\r\n\t/\r\n\tto the/fil\r\n\te.e\r\n\txt?que\r\n\try#ha\r\n\tsh \r\n\t ");
   Assert.equal(url.spec, "http://example.com/path/to%20the/file.ext?query#hash");
 
   // These setters should escape \r\n\t, not filter them.
   var url = stringToURL("http://test.com/path?query#hash");
-  url.filePath = "pa\r\n\tth";
+  url = url.mutate().setFilePath("pa\r\n\tth").finalize();
   Assert.equal(url.spec, "http://test.com/pa%0D%0A%09th?query#hash");
   url.query = "qu\r\n\tery";
   Assert.equal(url.spec, "http://test.com/pa%0D%0A%09th?qu%0D%0A%09ery#hash");
   url.ref = "ha\r\n\tsh";
   Assert.equal(url.spec, "http://test.com/pa%0D%0A%09th?qu%0D%0A%09ery#ha%0D%0A%09sh");
   url = url.mutate().QueryInterface(Ci.nsIURLMutator).setFileName("fi\r\n\tle.name").finalize();
   Assert.equal(url.spec, "http://test.com/fi%0D%0A%09le.name?qu%0D%0A%09ery#ha%0D%0A%09sh");
 
@@ -399,17 +400,17 @@ add_test(function test_encode_C0_and_spa
       continue;
     }
     var url = stringToURL("http://example.com/pa" + String.fromCharCode(i) + "th?qu" + String.fromCharCode(i) +"ery#ha" + String.fromCharCode(i) + "sh");
     Assert.equal(url.spec, "http://example.com/pa%" + toHex(i) + "th?qu%" + toHex(i) + "ery#ha%" + toHex(i) + "sh");
   }
 
   // Additionally, we need to check the setters.
   var url = stringToURL("http://example.com/path?query#hash");
-  url.filePath = "pa\0th";
+  url = url.mutate().setFilePath("pa\0th").finalize();
   Assert.equal(url.spec, "http://example.com/pa%00th?query#hash");
   url.query = "qu\0ery";
   Assert.equal(url.spec, "http://example.com/pa%00th?qu%00ery#hash");
   url.ref = "ha\0sh";
   Assert.equal(url.spec, "http://example.com/pa%00th?qu%00ery#ha%00sh");
   url = url.mutate().QueryInterface(Ci.nsIURLMutator).setFileName("fi\0le.name").finalize();
   Assert.equal(url.spec, "http://example.com/fi%00le.name?qu%00ery#ha%00sh");
 
--- a/toolkit/content/contentAreaUtils.js
+++ b/toolkit/content/contentAreaUtils.js
@@ -1085,20 +1085,22 @@ function getNormalizedLeafName(aFile, aD
   return aFile;
 }
 
 function getDefaultExtension(aFilename, aURI, aContentType) {
   if (aContentType == "text/plain" || aContentType == "application/octet-stream" || aURI.scheme == "ftp")
     return ""; // temporary fix for bug 120327
 
   // First try the extension from the filename
-  const stdURLContractID = "@mozilla.org/network/standard-url;1";
-  const stdURLIID = Components.interfaces.nsIURL;
-  var url = Components.classes[stdURLContractID].createInstance(stdURLIID);
-  url.filePath = aFilename;
+  var url = Components.classes["@mozilla.org/network/standard-url-mutator;1"]
+                      .createInstance(Components.interfaces.nsIURIMutator)
+                      .setSpec("http://example.com") // construct the URL
+                      .setFilePath(aFilename)
+                      .finalize()
+                      .QueryInterface(Components.interfaces.nsIURL);
 
   var ext = url.fileExtension;
 
   // This mirrors some code in nsExternalHelperAppService::DoContent
   // Use the filename first and then the URI if that fails
 
   var mimeInfo = getMIMEInfoForType(aContentType, ext);