Bug 1432320 - (Part 2) Change calls to nsIURL.{fileName,fileBaseName,fileExtension} setters to use nsIURLMutator
MozReview-Commit-ID: D5aTl1i14gI
--- a/dom/base/nsContentAreaDragDrop.cpp
+++ b/dom/base/nsContentAreaDragDrop.cpp
@@ -34,16 +34,17 @@
#include "nsFrameLoader.h"
#include "nsIWebNavigation.h"
#include "nsIDocShell.h"
#include "nsIContent.h"
#include "nsIImageLoadingContent.h"
#include "nsITextControlElement.h"
#include "nsUnicharUtils.h"
#include "nsIURL.h"
+#include "nsIURIMutator.h"
#include "nsIDocument.h"
#include "nsIScriptSecurityManager.h"
#include "nsIPrincipal.h"
#include "nsIDocShellTreeItem.h"
#include "nsIWebBrowserPersist.h"
#include "nsEscape.h"
#include "nsContentUtils.h"
#include "nsIMIMEService.h"
@@ -590,25 +591,25 @@ DragDataProducer::Produce(DataTransfer*
CopyUTF8toUTF16(spec, mImageSourceString);
bool validExtension;
if (extension.IsEmpty() ||
NS_FAILED(mimeInfo->ExtensionExists(extension,
&validExtension)) ||
!validExtension) {
// Fix the file extension in the URL
- nsresult rv = imgUrl->Clone(getter_AddRefs(imgUri));
- NS_ENSURE_SUCCESS(rv, rv);
-
- imgUrl = do_QueryInterface(imgUri);
-
nsAutoCString primaryExtension;
mimeInfo->GetPrimaryExtension(primaryExtension);
- imgUrl->SetFileExtension(primaryExtension);
+ rv = NS_MutateURI(imgUrl)
+ .Apply<nsIURLMutator>(&nsIURLMutator::SetFileExtension,
+ primaryExtension,
+ nullptr)
+ .Finalize(imgUrl);
+ NS_ENSURE_SUCCESS(rv, rv);
}
nsAutoCString fileName;
imgUrl->GetFileName(fileName);
NS_UnescapeURL(fileName);
// make the filename safe for the filesystem
--- a/dom/base/nsCopySupport.cpp
+++ b/dom/base/nsCopySupport.cpp
@@ -35,16 +35,17 @@
#include "nsIDocument.h"
#include "nsIDOMNode.h"
#include "nsIDOMElement.h"
#include "nsIDOMDocument.h"
#include "nsIHTMLDocument.h"
#include "nsGkAtoms.h"
#include "nsIFrame.h"
#include "nsIURI.h"
+#include "nsIURIMutator.h"
#include "nsISimpleEnumerator.h"
// image copy stuff
#include "nsIImageLoadingContent.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsContentUtils.h"
#include "nsContentCID.h"
@@ -646,25 +647,25 @@ static nsresult AppendImagePromise(nsITr
CopyUTF8toUTF16(spec, imageSourceString);
bool validExtension;
if (extension.IsEmpty() ||
NS_FAILED(mimeInfo->ExtensionExists(extension,
&validExtension)) ||
!validExtension) {
// Fix the file extension in the URL
- rv = imgUrl->Clone(getter_AddRefs(imgUri));
- NS_ENSURE_SUCCESS(rv, rv);
-
- imgUrl = do_QueryInterface(imgUri);
-
nsAutoCString primaryExtension;
mimeInfo->GetPrimaryExtension(primaryExtension);
- imgUrl->SetFileExtension(primaryExtension);
+ rv = NS_MutateURI(imgUri)
+ .Apply<nsIURLMutator>(&nsIURLMutator::SetFileExtension,
+ primaryExtension,
+ nullptr)
+ .Finalize(imgUrl);
+ NS_ENSURE_SUCCESS(rv, rv);
}
nsAutoCString fileName;
imgUrl->GetFileName(fileName);
NS_UnescapeURL(fileName);
// make the filename safe for the filesystem
--- a/dom/webbrowserpersist/nsWebBrowserPersist.cpp
+++ b/dom/webbrowserpersist/nsWebBrowserPersist.cpp
@@ -33,16 +33,17 @@
#include "nsCRT.h"
#include "nsContentCID.h"
#include "nsStreamUtils.h"
#include "nsCExternalHandlerService.h"
#include "nsIURL.h"
#include "nsIFileURL.h"
+#include "nsIURIMutator.h"
#include "nsIWebProgressListener.h"
#include "nsIAuthPrompt.h"
#include "nsIPrompt.h"
#include "nsISHEntry.h"
#include "nsIWebPageDescriptor.h"
#include "nsIFormControl.h"
#include "nsContentUtils.h"
@@ -850,21 +851,29 @@ NS_IMETHODIMP nsWebBrowserPersist::OnSta
NS_ASSERTION(!((mPersistFlags & PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION) &&
(mPersistFlags & PERSIST_FLAGS_NO_CONVERSION)),
"Conflict in persist flags: both AUTODETECT and NO_CONVERSION set");
if (mPersistFlags & PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION)
SetApplyConversionIfNeeded(channel);
if (data->mCalcFileExt && !(mPersistFlags & PERSIST_FLAGS_DONT_CHANGE_FILENAMES))
{
+ nsCOMPtr<nsIURI> uriWithExt;
// this is the first point at which the server can tell us the mimetype
- CalculateAndAppendFileExt(data->mFile, channel, data->mOriginalLocation);
+ nsresult rv = CalculateAndAppendFileExt(data->mFile, channel, data->mOriginalLocation, uriWithExt);
+ if (NS_SUCCEEDED(rv)) {
+ data->mFile = uriWithExt;
+ }
// now make filename conformant and unique
- CalculateUniqueFilename(data->mFile);
+ nsCOMPtr<nsIURI> uniqueFilenameURI;
+ rv = CalculateUniqueFilename(data->mFile, uniqueFilenameURI);
+ if (NS_SUCCEEDED(rv)) {
+ data->mFile = uniqueFilenameURI;
+ }
}
// compare uris and bail before we add to output map if they are equal
bool isEqual = false;
if (NS_SUCCEEDED(data->mFile->Equals(data->mOriginalLocation, &isEqual))
&& isEqual)
{
// remove from output map
@@ -1954,17 +1963,17 @@ void nsWebBrowserPersist::CleanupLocalFi
file->Remove(true);
}
}
}
}
}
nsresult
-nsWebBrowserPersist::CalculateUniqueFilename(nsIURI *aURI)
+nsWebBrowserPersist::CalculateUniqueFilename(nsIURI *aURI, nsCOMPtr<nsIURI>& aOutURI)
{
nsCOMPtr<nsIURL> url(do_QueryInterface(aURI));
NS_ENSURE_TRUE(url, NS_ERROR_FAILURE);
bool nameHasChanged = false;
nsresult rv;
// Get the old filename
@@ -2106,20 +2115,26 @@ nsWebBrowserPersist::CalculateUniqueFile
// Resync the URI with the file after the extension has been appended
nsresult rv;
nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(aURI, &rv);
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
fileURL->SetFile(localFile); // this should recalculate uri
}
else
{
- url->SetFileName(filename);
+ return NS_MutateURI(url)
+ .Apply<nsIURLMutator>(&nsIURLMutator::SetFileName,
+ filename,
+ nullptr)
+ .Finalize(aOutURI);
}
}
+ // TODO (:valentin) This method should always clone aURI
+ aOutURI = aURI;
return NS_OK;
}
nsresult
nsWebBrowserPersist::MakeFilenameFromURI(nsIURI *aURI, nsString &aFilename)
{
// Try to get filename from the URI.
@@ -2178,19 +2193,22 @@ nsWebBrowserPersist::MakeFilenameFromURI
}
aFilename = fileName;
return NS_OK;
}
nsresult
-nsWebBrowserPersist::CalculateAndAppendFileExt(nsIURI *aURI, nsIChannel *aChannel, nsIURI *aOriginalURIWithExtension)
+nsWebBrowserPersist::CalculateAndAppendFileExt(nsIURI *aURI,
+ nsIChannel *aChannel,
+ nsIURI *aOriginalURIWithExtension,
+ nsCOMPtr<nsIURI>& aOutURI)
{
- nsresult rv;
+ nsresult rv = NS_OK;
if (!mMIMEService)
{
mMIMEService = do_GetService(NS_MIMESERVICE_CONTRACTID, &rv);
NS_ENSURE_TRUE(mMIMEService, NS_ERROR_FAILURE);
}
nsAutoCString contentType;
@@ -2275,23 +2293,29 @@ nsWebBrowserPersist::CalculateAndAppendF
// Resync the URI with the file after the extension has been appended
nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(aURI, &rv);
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
fileURL->SetFile(localFile); // this should recalculate uri
}
else
{
- url->SetFileName(newFileName);
+ return NS_MutateURI(url)
+ .Apply<nsIURLMutator>(&nsIURLMutator::SetFileName,
+ newFileName,
+ nullptr)
+ .Finalize(aOutURI);
}
}
}
}
+ // TODO (:valentin) This method should always clone aURI
+ aOutURI = aURI;
return NS_OK;
}
nsresult
nsWebBrowserPersist::MakeOutputStream(
nsIURI *aURI, nsIOutputStream **aOutputStream)
{
nsresult rv;
@@ -2678,20 +2702,24 @@ nsWebBrowserPersist::SaveSubframeContent
nsAutoString newFrameDataPath(aData->mFilename);
// Append _data
newFrameDataPath.AppendLiteral("_data");
rv = AppendPathToURI(frameDataURI, newFrameDataPath);
NS_ENSURE_SUCCESS(rv, rv);
// Make frame document & data path conformant and unique
- rv = CalculateUniqueFilename(frameURI);
+ nsCOMPtr<nsIURI> out;
+ rv = CalculateUniqueFilename(frameURI, out);
NS_ENSURE_SUCCESS(rv, rv);
- rv = CalculateUniqueFilename(frameDataURI);
+ frameURI = out;
+
+ rv = CalculateUniqueFilename(frameDataURI, out);
NS_ENSURE_SUCCESS(rv, rv);
+ frameDataURI = out;
mCurrentThingsToPersist++;
// We shouldn't use SaveDocumentInternal for the contents
// of frames that are not documents, e.g. images.
if (DocumentEncoderExists(contentType.get())) {
auto toWalk = mozilla::MakeUnique<WalkData>();
toWalk->mDocument = aFrameContent;
--- a/dom/webbrowserpersist/nsWebBrowserPersist.h
+++ b/dom/webbrowserpersist/nsWebBrowserPersist.h
@@ -100,18 +100,19 @@ private:
nsIFile *aFile, nsIOutputStream **aOutputStream);
nsresult MakeOutputStreamFromURI(nsIURI *aURI, nsIOutputStream **aOutStream);
nsresult CreateChannelFromURI(nsIURI *aURI, nsIChannel **aChannel);
nsresult StartUpload(nsIStorageStream *aOutStream, nsIURI *aDestinationURI,
const nsACString &aContentType);
nsresult StartUpload(nsIInputStream *aInputStream, nsIURI *aDestinationURI,
const nsACString &aContentType);
nsresult CalculateAndAppendFileExt(nsIURI *aURI, nsIChannel *aChannel,
- nsIURI *aOriginalURIWithExtension);
- nsresult CalculateUniqueFilename(nsIURI *aURI);
+ nsIURI *aOriginalURIWithExtension,
+ nsCOMPtr<nsIURI>& aOutURI);
+ nsresult CalculateUniqueFilename(nsIURI *aURI, nsCOMPtr<nsIURI>& aOutURI);
nsresult MakeFilenameFromURI(
nsIURI *aURI, nsString &aFilename);
nsresult StoreURI(
const char *aURI,
bool aNeedsPersisting = true,
URIData **aData = nullptr);
nsresult StoreURI(
nsIURI *aURI,
--- a/netwerk/test/unit/test_standardurl.js
+++ b/netwerk/test/unit/test_standardurl.js
@@ -298,44 +298,56 @@ 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", "hostPort", "host", "pathQueryRef", "ref",
- "query", "fileName", "filePath", "fileBaseName", "fileExtension"];
+ "query", "filePath"];
for (let prop of properties) {
Assert.throws(() => url[prop] = hugeString,
/NS_ERROR_MALFORMED_URI/,
`Passing a huge string to "${prop}" should throw`);
}
Assert.throws(() => { url = url.mutate().setSpec(hugeString).finalize(); },
/NS_ERROR_MALFORMED_URI/,
"Passing a huge string to setSpec should throw");
+ let setters = [
+ { method: "setFileName", qi: Ci.nsIURLMutator },
+ { method: "setFileExtension", qi: Ci.nsIURLMutator },
+ { method: "setFileBaseName", qi: Ci.nsIURLMutator },
+ ];
+
+ for (let prop of setters) {
+ Assert.throws(() => url = url.mutate().QueryInterface(prop.qi)[prop.method](hugeString).finalize(),
+ /NS_ERROR_MALFORMED_URI/,
+ `Passing a huge string to "${prop.method}" should throw`);
+ }
+
run_next_test();
});
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";
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.fileName = "fi\r\n\tle.name";
+ 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");
run_next_test();
});
add_test(function test_backslashReplacement()
{
var url = stringToURL("http:\\\\test.com\\path/to\\file?query\\backslash#hash\\");
@@ -394,17 +406,17 @@ add_test(function test_encode_C0_and_spa
// Additionally, we need to check the setters.
var url = stringToURL("http://example.com/path?query#hash");
url.filePath = "pa\0th";
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.fileName = "fi\0le.name";
+ 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");
run_next_test();
});
add_test(function test_ipv4Normalize()
{
var localIPv4s =