--- a/caps/nsNullPrincipalURI.cpp
+++ b/caps/nsNullPrincipalURI.cpp
@@ -266,16 +266,24 @@ NS_IMETHODIMP
nsNullPrincipalURI::CloneIgnoringRef(nsIURI **_newURI)
{
// GetRef/SetRef not supported by nsNullPrincipalURI, so
// CloneIgnoringRef() is the same as Clone().
return Clone(_newURI);
}
NS_IMETHODIMP
+nsNullPrincipalURI::CloneWithNewRef(const nsACString& newRef, nsIURI **_newURI)
+{
+ // GetRef/SetRef not supported by nsNullPrincipalURI, so
+ // CloneWithNewRef() is the same as Clone().
+ return Clone(_newURI);
+}
+
+NS_IMETHODIMP
nsNullPrincipalURI::Equals(nsIURI *aOther, bool *_equals)
{
*_equals = false;
RefPtr<nsNullPrincipalURI> otherURI;
nsresult rv = aOther->QueryInterface(kNullPrincipalURIImplementationCID,
getter_AddRefs(otherURI));
if (NS_SUCCEEDED(rv)) {
*_equals = mPath == otherURI->mPath;
--- a/dom/base/nsHostObjectURI.cpp
+++ b/dom/base/nsHostObjectURI.cpp
@@ -156,21 +156,22 @@ nsHostObjectURI::SetScheme(const nsACStr
// with a different protocol handler that doesn't expect us to be carrying
// around a principal with nsIURIWithPrincipal.
return NS_ERROR_FAILURE;
}
// nsIURI methods:
nsresult
nsHostObjectURI::CloneInternal(mozilla::net::nsSimpleURI::RefHandlingEnum aRefHandlingMode,
+ const nsACString& newRef,
nsIURI** aClone)
{
nsCOMPtr<nsIURI> simpleClone;
nsresult rv =
- mozilla::net::nsSimpleURI::CloneInternal(aRefHandlingMode, getter_AddRefs(simpleClone));
+ mozilla::net::nsSimpleURI::CloneInternal(aRefHandlingMode, newRef, getter_AddRefs(simpleClone));
NS_ENSURE_SUCCESS(rv, rv);
#ifdef DEBUG
RefPtr<nsHostObjectURI> uriCheck;
rv = simpleClone->QueryInterface(kHOSTOBJECTURICID, getter_AddRefs(uriCheck));
MOZ_ASSERT(NS_SUCCEEDED(rv) && uriCheck);
#endif
--- a/dom/base/nsHostObjectURI.h
+++ b/dom/base/nsHostObjectURI.h
@@ -44,24 +44,30 @@ public:
NS_DECL_NSISERIALIZABLE
NS_DECL_NSICLASSINFO
NS_DECL_NSIIPCSERIALIZABLEURI
NS_IMETHOD SetScheme(const nsACString &aProtocol) override;
// Override CloneInternal() and EqualsInternal()
virtual nsresult CloneInternal(RefHandlingEnum aRefHandlingMode,
+ const nsACString& newRef,
nsIURI** aClone) override;
virtual nsresult EqualsInternal(nsIURI* aOther,
RefHandlingEnum aRefHandlingMode,
bool* aResult) override;
// Override StartClone to hand back a nsHostObjectURI
- virtual mozilla::net::nsSimpleURI* StartClone(RefHandlingEnum /* unused */) override
- { return new nsHostObjectURI(); }
+ virtual mozilla::net::nsSimpleURI* StartClone(RefHandlingEnum refHandlingMode,
+ const nsACString& newRef) override
+ {
+ nsHostObjectURI* url = new nsHostObjectURI();
+ SetRefOnClone(url, refHandlingMode, newRef);
+ return url;
+ }
nsCOMPtr<nsIPrincipal> mPrincipal;
RefPtr<mozilla::dom::BlobImpl> mBlobImpl;
protected:
virtual ~nsHostObjectURI() {}
};
--- a/dom/jsurl/nsJSProtocolHandler.cpp
+++ b/dom/jsurl/nsJSProtocolHandler.cpp
@@ -1357,28 +1357,31 @@ nsJSURI::Deserialize(const mozilla::ipc:
} else {
mBaseURI = nullptr;
}
return true;
}
// nsSimpleURI methods:
/* virtual */ mozilla::net::nsSimpleURI*
-nsJSURI::StartClone(mozilla::net::nsSimpleURI::RefHandlingEnum /* ignored */)
+nsJSURI::StartClone(mozilla::net::nsSimpleURI::RefHandlingEnum refHandlingMode,
+ const nsACString& newRef)
{
nsCOMPtr<nsIURI> baseClone;
if (mBaseURI) {
// Note: We preserve ref on *base* URI, regardless of ref handling mode.
nsresult rv = mBaseURI->Clone(getter_AddRefs(baseClone));
if (NS_FAILED(rv)) {
return nullptr;
}
}
- return new nsJSURI(baseClone);
+ nsJSURI* url = new nsJSURI(baseClone);
+ SetRefOnClone(url, refHandlingMode, newRef);
+ return url;
}
/* virtual */ nsresult
nsJSURI::EqualsInternal(nsIURI* aOther,
mozilla::net::nsSimpleURI::RefHandlingEnum aRefHandlingMode,
bool* aResult)
{
NS_ENSURE_ARG_POINTER(aOther);
--- a/dom/jsurl/nsJSProtocolHandler.h
+++ b/dom/jsurl/nsJSProtocolHandler.h
@@ -74,17 +74,18 @@ public:
nsIURI* GetBaseURI() const
{
return mBaseURI;
}
NS_DECL_ISUPPORTS_INHERITED
// nsIURI overrides
- virtual mozilla::net::nsSimpleURI* StartClone(RefHandlingEnum refHandlingMode) override;
+ virtual mozilla::net::nsSimpleURI* StartClone(RefHandlingEnum refHandlingMode,
+ const nsACString& newRef) override;
// nsISerializable overrides
NS_IMETHOD Read(nsIObjectInputStream* aStream) override;
NS_IMETHOD Write(nsIObjectOutputStream* aStream) override;
// nsIIPCSerializableURI overrides
NS_DECL_NSIIPCSERIALIZABLEURI
--- a/image/decoders/icon/nsIconURI.cpp
+++ b/image/decoders/icon/nsIconURI.cpp
@@ -450,16 +450,25 @@ NS_IMETHODIMP
nsMozIconURI::CloneIgnoringRef(nsIURI** result)
{
// GetRef/SetRef not supported by nsMozIconURI, so
// CloneIgnoringRef() is the same as Clone().
return Clone(result);
}
NS_IMETHODIMP
+nsMozIconURI::CloneWithNewRef(const nsACString& newRef, nsIURI** result)
+{
+ // GetRef/SetRef not supported by nsMozIconURI, so
+ // CloneWithNewRef() is the same as Clone().
+ return Clone(result);
+}
+
+
+NS_IMETHODIMP
nsMozIconURI::Resolve(const nsACString& relativePath, nsACString& result)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMozIconURI::GetAsciiSpec(nsACString& aSpecA)
{
--- a/modules/libjar/nsJARURI.cpp
+++ b/modules/libjar/nsJARURI.cpp
@@ -523,16 +523,30 @@ nsJARURI::CloneIgnoringRef(nsIURI **resu
rv = CloneWithJARFileInternal(mJARFile, eIgnoreRef, getter_AddRefs(uri));
if (NS_FAILED(rv)) return rv;
uri.forget(result);
return NS_OK;
}
NS_IMETHODIMP
+nsJARURI::CloneWithNewRef(const nsACString& newRef, nsIURI **result)
+{
+ nsresult rv;
+
+ nsCOMPtr<nsIJARURI> uri;
+ rv = CloneWithJARFileInternal(mJARFile, eReplaceRef, newRef,
+ getter_AddRefs(uri));
+ if (NS_FAILED(rv)) return rv;
+
+ uri.forget(result);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
nsJARURI::Resolve(const nsACString &relativePath, nsACString &result)
{
nsresult rv;
nsCOMPtr<nsIIOService> ioServ(do_GetIOService(&rv));
if (NS_FAILED(rv))
return rv;
@@ -779,33 +793,45 @@ nsJARURI::CloneWithJARFile(nsIURI *jarFi
return CloneWithJARFileInternal(jarFile, eHonorRef, result);
}
nsresult
nsJARURI::CloneWithJARFileInternal(nsIURI *jarFile,
nsJARURI::RefHandlingEnum refHandlingMode,
nsIJARURI **result)
{
+ return CloneWithJARFileInternal(jarFile, refHandlingMode, EmptyCString(), result);
+}
+
+nsresult
+nsJARURI::CloneWithJARFileInternal(nsIURI *jarFile,
+ nsJARURI::RefHandlingEnum refHandlingMode,
+ const nsACString& newRef,
+ nsIJARURI **result)
+{
if (!jarFile) {
return NS_ERROR_INVALID_ARG;
}
nsresult rv;
nsCOMPtr<nsIURI> newJARFile;
rv = jarFile->Clone(getter_AddRefs(newJARFile));
if (NS_FAILED(rv)) return rv;
NS_TryToSetImmutable(newJARFile);
nsCOMPtr<nsIURI> newJAREntryURI;
- rv = refHandlingMode == eHonorRef ?
- mJAREntry->Clone(getter_AddRefs(newJAREntryURI)) :
- mJAREntry->CloneIgnoringRef(getter_AddRefs(newJAREntryURI));
-
+ if (refHandlingMode == eHonorRef) {
+ rv = mJAREntry->Clone(getter_AddRefs(newJAREntryURI));
+ } else if (refHandlingMode == eReplaceRef) {
+ rv = mJAREntry->CloneWithNewRef(newRef, getter_AddRefs(newJAREntryURI));
+ } else {
+ rv = mJAREntry->CloneIgnoringRef(getter_AddRefs(newJAREntryURI));
+ }
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIURL> newJAREntry(do_QueryInterface(newJAREntryURI));
NS_ASSERTION(newJAREntry, "This had better QI to nsIURL!");
nsJARURI* uri = new nsJARURI();
NS_ADDREF(uri);
uri->mJARFile = newJARFile;
--- a/modules/libjar/nsJARURI.h
+++ b/modules/libjar/nsJARURI.h
@@ -62,28 +62,33 @@ public:
nsresult SetSpecWithBase(const nsACString& aSpec, nsIURI* aBaseURL);
protected:
virtual ~nsJARURI();
// enum used in a few places to specify how .ref attribute should be handled
enum RefHandlingEnum {
eIgnoreRef,
- eHonorRef
+ eHonorRef,
+ eReplaceRef
};
// Helper to share code between Equals methods.
virtual nsresult EqualsInternal(nsIURI* other,
RefHandlingEnum refHandlingMode,
bool* result);
- // Helper to share code between Clone methods.
+ // Helpers to share code between Clone methods.
nsresult CloneWithJARFileInternal(nsIURI *jarFile,
RefHandlingEnum refHandlingMode,
nsIJARURI **result);
+ nsresult CloneWithJARFileInternal(nsIURI *jarFile,
+ RefHandlingEnum refHandlingMode,
+ const nsACString& newRef,
+ nsIJARURI **result);
nsCOMPtr<nsIURI> mJARFile;
// mJarEntry stored as a URL so that we can easily access things
// like extensions, refs, etc.
nsCOMPtr<nsIURL> mJAREntry;
nsCString mCharsetHint;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsJARURI, NS_THIS_JARURI_IMPL_CID)
--- a/netwerk/base/nsIOService.cpp
+++ b/netwerk/base/nsIOService.cpp
@@ -619,16 +619,22 @@ nsIOService::NewURI(const nsACString &aS
nsAutoCString scheme;
nsresult rv = ExtractScheme(aSpec, scheme);
if (NS_FAILED(rv)) {
// then aSpec is relative
if (!aBaseURI)
return NS_ERROR_MALFORMED_URI;
+ if (!aSpec.IsEmpty() && aSpec[0] == '#') {
+ // Looks like a reference instead of a fully-specified URI.
+ // --> initialize |uri| as a clone of |aBaseURI|, with ref appended.
+ return aBaseURI->CloneWithNewRef(aSpec, result);
+ }
+
rv = aBaseURI->GetScheme(scheme);
if (NS_FAILED(rv)) return rv;
}
// now get the handler for this scheme
nsCOMPtr<nsIProtocolHandler> handler;
rv = GetProtocolHandler(scheme.get(), getter_AddRefs(handler));
if (NS_FAILED(rv)) return rv;
--- a/netwerk/base/nsIURI.idl
+++ b/netwerk/base/nsIURI.idl
@@ -241,16 +241,22 @@ interface nsIURI : nsISupports
boolean equalsExceptRef(in nsIURI other);
/**
* Clones the current URI, clearing the 'ref' attribute in the clone.
*/
nsIURI cloneIgnoringRef();
/**
+ * Clones the current URI, replacing the 'ref' attribute in the clone with
+ * the ref supplied.
+ */
+ nsIURI cloneWithNewRef(in AUTF8String newRef);
+
+ /**
* returns a string for the current URI with the ref element cleared.
*/
readonly attribute AUTF8String specIgnoringRef;
/**
* Returns if there is a reference portion (the part after the "#") of the URI.
*/
readonly attribute boolean hasRef;
--- a/netwerk/base/nsSimpleNestedURI.cpp
+++ b/netwerk/base/nsSimpleNestedURI.cpp
@@ -144,30 +144,37 @@ nsSimpleNestedURI::EqualsInternal(nsIURI
}
}
}
return NS_OK;
}
/* virtual */ nsSimpleURI*
-nsSimpleNestedURI::StartClone(nsSimpleURI::RefHandlingEnum refHandlingMode)
+nsSimpleNestedURI::StartClone(nsSimpleURI::RefHandlingEnum refHandlingMode,
+ const nsACString& newRef)
{
NS_ENSURE_TRUE(mInnerURI, nullptr);
nsCOMPtr<nsIURI> innerClone;
- nsresult rv = refHandlingMode == eHonorRef ?
- mInnerURI->Clone(getter_AddRefs(innerClone)) :
- mInnerURI->CloneIgnoringRef(getter_AddRefs(innerClone));
+ nsresult rv;
+ if (refHandlingMode == eHonorRef) {
+ rv = mInnerURI->Clone(getter_AddRefs(innerClone));
+ } else if (refHandlingMode == eReplaceRef) {
+ rv = mInnerURI->CloneWithNewRef(newRef, getter_AddRefs(innerClone));
+ } else {
+ rv = mInnerURI->CloneIgnoringRef(getter_AddRefs(innerClone));
+ }
if (NS_FAILED(rv)) {
return nullptr;
}
nsSimpleNestedURI* url = new nsSimpleNestedURI(innerClone);
+ SetRefOnClone(url, refHandlingMode, newRef);
url->SetMutable(false);
return url;
}
// nsIClassInfo overrides
NS_IMETHODIMP
--- a/netwerk/base/nsSimpleNestedURI.h
+++ b/netwerk/base/nsSimpleNestedURI.h
@@ -46,17 +46,18 @@ public:
NS_DECL_NSINESTEDURI
// Overrides for various methods nsSimpleURI implements follow.
// nsSimpleURI overrides
virtual nsresult EqualsInternal(nsIURI* other,
RefHandlingEnum refHandlingMode,
bool* result) override;
- virtual nsSimpleURI* StartClone(RefHandlingEnum refHandlingMode) override;
+ virtual nsSimpleURI* StartClone(RefHandlingEnum refHandlingMode,
+ const nsACString& newRef) override;
// nsISerializable overrides
NS_IMETHOD Read(nsIObjectInputStream* aStream) override;
NS_IMETHOD Write(nsIObjectOutputStream* aStream) override;
// nsIIPCSerializableURI overrides
NS_DECL_NSIIPCSERIALIZABLEURI
--- a/netwerk/base/nsSimpleURI.cpp
+++ b/netwerk/base/nsSimpleURI.cpp
@@ -466,49 +466,68 @@ nsSimpleURI::SchemeIs(const char *i_Sche
} else {
*o_Equals = false;
}
return NS_OK;
}
/* virtual */ nsSimpleURI*
-nsSimpleURI::StartClone(nsSimpleURI::RefHandlingEnum /* ignored */)
+nsSimpleURI::StartClone(nsSimpleURI::RefHandlingEnum refHandlingMode,
+ const nsACString& newRef)
{
- return new nsSimpleURI();
+ nsSimpleURI* url = new nsSimpleURI();
+ SetRefOnClone(url, refHandlingMode, newRef);
+ return url;
+}
+
+/* virtual */ void
+nsSimpleURI::SetRefOnClone(nsSimpleURI* url,
+ nsSimpleURI::RefHandlingEnum refHandlingMode,
+ const nsACString& newRef)
+{
+ if (refHandlingMode == eHonorRef) {
+ url->mRef = mRef;
+ url->mIsRefValid = mIsRefValid;
+ } else if (refHandlingMode == eReplaceRef) {
+ url->SetRef(newRef);
+ }
}
NS_IMETHODIMP
nsSimpleURI::Clone(nsIURI** result)
{
- return CloneInternal(eHonorRef, result);
+ return CloneInternal(eHonorRef, EmptyCString(), result);
}
NS_IMETHODIMP
nsSimpleURI::CloneIgnoringRef(nsIURI** result)
{
- return CloneInternal(eIgnoreRef, result);
+ return CloneInternal(eIgnoreRef, EmptyCString(), result);
+}
+
+NS_IMETHODIMP
+nsSimpleURI::CloneWithNewRef(const nsACString &newRef, nsIURI** result)
+{
+ return CloneInternal(eReplaceRef, newRef, result);
}
nsresult
nsSimpleURI::CloneInternal(nsSimpleURI::RefHandlingEnum refHandlingMode,
+ const nsACString &newRef,
nsIURI** result)
{
- RefPtr<nsSimpleURI> url = StartClone(refHandlingMode);
+ RefPtr<nsSimpleURI> url = StartClone(refHandlingMode, newRef);
if (!url)
return NS_ERROR_OUT_OF_MEMORY;
// Note: |url| may well have mMutable false at this point, so
// don't call any setter methods.
url->mScheme = mScheme;
url->mPath = mPath;
- if (refHandlingMode == eHonorRef) {
- url->mRef = mRef;
- url->mIsRefValid = mIsRefValid;
- }
url.forget(result);
return NS_OK;
}
NS_IMETHODIMP
nsSimpleURI::Resolve(const nsACString &relativePath, nsACString &result)
{
--- a/netwerk/base/nsSimpleURI.h
+++ b/netwerk/base/nsSimpleURI.h
@@ -57,36 +57,44 @@ public:
// - nsBlobURI: mPrincipal
virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
protected:
// enum used in a few places to specify how .ref attribute should be handled
enum RefHandlingEnum {
eIgnoreRef,
- eHonorRef
+ eHonorRef,
+ eReplaceRef
};
// Helper to share code between Equals methods.
virtual nsresult EqualsInternal(nsIURI* other,
RefHandlingEnum refHandlingMode,
bool* result);
// Helper to be used by inherited classes who want to test
// equality given an assumed nsSimpleURI. This must NOT check
// the passed-in other for QI to our CID.
bool EqualsInternal(nsSimpleURI* otherUri, RefHandlingEnum refHandlingMode);
+ // Used by StartClone (and versions of StartClone in subclasses) to
+ // handle the ref in the right way for clones.
+ void SetRefOnClone(nsSimpleURI* url, RefHandlingEnum refHandlingMode,
+ const nsACString& newRef);
+
// NOTE: This takes the refHandlingMode as an argument because
// nsSimpleNestedURI's specialized version needs to know how to clone
// its inner URI.
- virtual nsSimpleURI* StartClone(RefHandlingEnum refHandlingMode);
+ virtual nsSimpleURI* StartClone(RefHandlingEnum refHandlingMode,
+ const nsACString& newRef);
// Helper to share code between Clone methods.
virtual nsresult CloneInternal(RefHandlingEnum refHandlingMode,
+ const nsACString &newRef,
nsIURI** clone);
nsCString mScheme;
nsCString mPath; // NOTE: mPath does not include ref, as an optimization
nsCString mRef; // so that URIs with different refs can share string data.
bool mMutable;
bool mIsRefValid; // To distinguish between empty-ref and no-ref.
};
--- a/netwerk/base/nsStandardURL.cpp
+++ b/netwerk/base/nsStandardURL.cpp
@@ -1305,17 +1305,17 @@ nsStandardURL::SetSpec(const nsACString
net_FilterURIString(flat, filteredURI);
if (filteredURI.Length() == 0) {
return NS_ERROR_MALFORMED_URI;
}
// Make a backup of the curent URL
nsStandardURL prevURL(false,false);
- prevURL.CopyMembers(this, eHonorRef);
+ prevURL.CopyMembers(this, eHonorRef, EmptyCString());
Clear();
if (IsSpecialProtocol(filteredURI)) {
// Bug 652186: Replace all backslashes with slashes when parsing paths
// Stop when we reach the query or the hash.
nsAutoCString::iterator start;
nsAutoCString::iterator end;
filteredURI.BeginWriting(start);
@@ -1346,17 +1346,17 @@ nsStandardURL::SetSpec(const nsACString
if (mURLType == URLTYPE_AUTHORITY && mHost.mLen == -1) {
rv = NS_ERROR_MALFORMED_URI;
}
if (NS_FAILED(rv)) {
Clear();
// If parsing the spec has failed, restore the old URL
// so we don't end up with an empty URL.
- CopyMembers(&prevURL, eHonorRef);
+ CopyMembers(&prevURL, eHonorRef, EmptyCString());
return rv;
}
if (LOG_ENABLED()) {
LOG((" spec = %s\n", mSpec.get()));
LOG((" port = %d\n", mPort));
LOG((" scheme = (%u,%d)\n", mScheme.mPos, mScheme.mLen));
LOG((" authority = (%u,%d)\n", mAuthority.mPos, mAuthority.mLen));
@@ -2036,45 +2036,53 @@ nsStandardURL::StartClone()
{
nsStandardURL *clone = new nsStandardURL();
return clone;
}
NS_IMETHODIMP
nsStandardURL::Clone(nsIURI **result)
{
- return CloneInternal(eHonorRef, result);
+ return CloneInternal(eHonorRef, EmptyCString(), result);
}
NS_IMETHODIMP
nsStandardURL::CloneIgnoringRef(nsIURI **result)
{
- return CloneInternal(eIgnoreRef, result);
+ return CloneInternal(eIgnoreRef, EmptyCString(), result);
+}
+
+NS_IMETHODIMP
+nsStandardURL::CloneWithNewRef(const nsACString& newRef, nsIURI **result)
+{
+ return CloneInternal(eReplaceRef, newRef, result);
}
nsresult
nsStandardURL::CloneInternal(nsStandardURL::RefHandlingEnum refHandlingMode,
+ const nsACString& newRef,
nsIURI **result)
{
RefPtr<nsStandardURL> clone = StartClone();
if (!clone)
return NS_ERROR_OUT_OF_MEMORY;
// Copy local members into clone.
// Also copies the cached members mFile, mHostA
- clone->CopyMembers(this, refHandlingMode, true);
+ clone->CopyMembers(this, refHandlingMode, newRef, true);
clone.forget(result);
return NS_OK;
}
nsresult nsStandardURL::CopyMembers(nsStandardURL * source,
- nsStandardURL::RefHandlingEnum refHandlingMode, bool copyCached)
+ nsStandardURL::RefHandlingEnum refHandlingMode, const nsACString& newRef,
+ bool copyCached)
{
mSpec = source->mSpec;
mDefaultPort = source->mDefaultPort;
mPort = source->mPort;
mScheme = source->mScheme;
mAuthority = source->mAuthority;
mUsername = source->mUsername;
mPassword = source->mPassword;
@@ -2101,16 +2109,18 @@ nsresult nsStandardURL::CopyMembers(nsSt
// The same state as after calling InvalidateCache()
mFile = nullptr;
mHostA = nullptr;
mSpecEncoding = eEncoding_Unknown;
}
if (refHandlingMode == eIgnoreRef) {
SetRef(EmptyCString());
+ } else if (refHandlingMode == eReplaceRef) {
+ SetRef(newRef);
}
return NS_OK;
}
NS_IMETHODIMP
nsStandardURL::Resolve(const nsACString &in, nsACString &out)
{
--- a/netwerk/base/nsStandardURL.h
+++ b/netwerk/base/nsStandardURL.h
@@ -144,33 +144,36 @@ public: /* internal -- HPUX compiler can
nsCOMPtr<nsIUnicodeEncoder> mEncoder;
};
friend class nsSegmentEncoder;
protected:
// enum used in a few places to specify how .ref attribute should be handled
enum RefHandlingEnum {
eIgnoreRef,
- eHonorRef
+ eHonorRef,
+ eReplaceRef
};
// Helper to share code between Equals and EqualsExceptRef
// NOTE: *not* virtual, because no one needs to override this so far...
nsresult EqualsInternal(nsIURI* unknownOther,
RefHandlingEnum refHandlingMode,
bool* result);
virtual nsStandardURL* StartClone();
// Helper to share code between Clone methods.
nsresult CloneInternal(RefHandlingEnum aRefHandlingMode,
+ const nsACString& newRef,
nsIURI** aClone);
// Helper method that copies member variables from the source StandardURL
// if copyCached = true, it will also copy mFile and mHostA
nsresult CopyMembers(nsStandardURL * source, RefHandlingEnum mode,
+ const nsACString& newRef,
bool copyCached = false);
// Helper for subclass implementation of GetFile(). Subclasses that map
// URIs to files in a special way should implement this method. It should
// ensure that our mFile is initialized, if it's possible.
// returns NS_ERROR_NO_INTERFACE if the url does not map to a file
virtual nsresult EnsureFile();
--- a/netwerk/protocol/about/nsAboutProtocolHandler.cpp
+++ b/netwerk/protocol/about/nsAboutProtocolHandler.cpp
@@ -387,33 +387,40 @@ nsNestedAboutURI::Write(nsIObjectOutputS
if (NS_FAILED(rv)) return rv;
}
return NS_OK;
}
// nsSimpleURI
/* virtual */ nsSimpleURI*
-nsNestedAboutURI::StartClone(nsSimpleURI::RefHandlingEnum aRefHandlingMode)
+nsNestedAboutURI::StartClone(nsSimpleURI::RefHandlingEnum aRefHandlingMode,
+ const nsACString& aNewRef)
{
// Sadly, we can't make use of nsSimpleNestedURI::StartClone here.
// However, this function is expected to exactly match that function,
// aside from the "new ns***URI()" call.
NS_ENSURE_TRUE(mInnerURI, nullptr);
nsCOMPtr<nsIURI> innerClone;
- nsresult rv = aRefHandlingMode == eHonorRef ?
- mInnerURI->Clone(getter_AddRefs(innerClone)) :
- mInnerURI->CloneIgnoringRef(getter_AddRefs(innerClone));
+ nsresult rv;
+ if (aRefHandlingMode == eHonorRef) {
+ rv = mInnerURI->Clone(getter_AddRefs(innerClone));
+ } else if (aRefHandlingMode == eReplaceRef) {
+ rv = mInnerURI->CloneWithNewRef(aNewRef, getter_AddRefs(innerClone));
+ } else {
+ rv = mInnerURI->CloneIgnoringRef(getter_AddRefs(innerClone));
+ }
if (NS_FAILED(rv)) {
return nullptr;
}
nsNestedAboutURI* url = new nsNestedAboutURI(innerClone, mBaseURI);
+ SetRefOnClone(url, aRefHandlingMode, aNewRef);
url->SetMutable(false);
return url;
}
// nsIClassInfo
NS_IMETHODIMP
nsNestedAboutURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
--- a/netwerk/protocol/about/nsAboutProtocolHandler.h
+++ b/netwerk/protocol/about/nsAboutProtocolHandler.h
@@ -65,17 +65,18 @@ public:
virtual ~nsNestedAboutURI() {}
// Override QI so we can QI to our CID as needed
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
// Override StartClone(), the nsISerializable methods, and
// GetClassIDNoAlloc; this last is needed to make our nsISerializable impl
// work right.
- virtual nsSimpleURI* StartClone(RefHandlingEnum aRefHandlingMode);
+ virtual nsSimpleURI* StartClone(RefHandlingEnum aRefHandlingMode,
+ const nsACString& newRef);
NS_IMETHOD Read(nsIObjectInputStream* aStream);
NS_IMETHOD Write(nsIObjectOutputStream* aStream);
NS_IMETHOD GetClassIDNoAlloc(nsCID *aClassIDNoAlloc);
nsIURI* GetBaseURI() const {
return mBaseURI;
}
--- a/netwerk/test/unit/test_URIs.js
+++ b/netwerk/test/unit/test_URIs.js
@@ -421,16 +421,29 @@ function do_test_uri_with_hash_suffix(aT
if (!origURI.ref) {
// These tests fail if origURI has a ref
do_info("testing cloneIgnoringRef on " + testURI.spec +
" is equal to no-ref version but not equal to ref version");
var cloneNoRef = testURI.cloneIgnoringRef();
do_check_uri_eq(cloneNoRef, origURI);
do_check_false(cloneNoRef.equals(testURI));
+
+ do_info("testing cloneWithNewRef on " + testURI.spec +
+ " with an empty ref is equal to no-ref version but not equal to ref version");
+ var cloneNewRef = testURI.cloneWithNewRef("");
+ do_check_uri_eq(cloneNewRef, origURI);
+ do_check_uri_eq(cloneNewRef, cloneNoRef);
+ do_check_false(cloneNewRef.equals(testURI));
+
+ do_info("testing cloneWithNewRef on " + origURI.spec +
+ " with the same new ref is equal to ref version and not equal to no-ref version");
+ cloneNewRef = origURI.cloneWithNewRef(aSuffix);
+ do_check_uri_eq(cloneNewRef, testURI);
+ do_check_true(cloneNewRef.equals(testURI));
}
do_check_property(aTest, testURI, "scheme");
do_check_property(aTest, testURI, "prePath");
if (!origURI.ref) {
// These don't work if it's a ref already because '+' doesn't give the right result
do_check_property(aTest, testURI, "path",
function(aStr) { return aStr + aSuffix; });
--- a/parser/xml/test/unit/results.js
+++ b/parser/xml/test/unit/results.js
@@ -134,17 +134,17 @@ var vectors = [
"sanitized": "<html><head></head><body><a></a><a>XXX</a><a>XXX</a></body></html>"
},
{
"data": "1<vmlframe xmlns=urn:schemas-microsoft-com:vml style=behavior:url(#default#vml);position:absolute;width:100%;height:100% src=test.vml#xss></vmlframe>",
"sanitized": "<html><head></head><body>1</body></html>"
},
{
"data": "1<a href=#><line xmlns=urn:schemas-microsoft-com:vml style=behavior:url(#default#vml);position:absolute href=javascript:alert(1) strokecolor=white strokeweight=1000px from=0 to=1000 /></a>",
- "sanitized": "<html><head></head><body>1<a></a></body></html>"
+ "sanitized": "<html><head></head><body>1<a href=\"#\"></a></body></html>"
},
{
"data": "<a style=\"behavior:url(#default#AnchorClick);\" folder=\"javascript:alert(1)\">XXX</a>",
"sanitized": "<html><head></head><body><a>XXX</a></body></html>"
},
{
"data": "<!--<img src=\"--><img src=x onerror=alert(1)//\">",
"sanitized": "<html><head></head><body><img></body></html>"
@@ -474,17 +474,17 @@ var vectors = [
"sanitized": "<html><head></head><body><div draggable=\"true\">\n\t<h1>Drop me</h1>\n</div>\n\n</body></html>"
},
{
"data": "<iframe src=\"view-source:http://www.example.org/\" frameborder=\"0\" style=\"width:400px;height:180px\"></iframe>\n\n<textarea type=\"text\" cols=\"50\" rows=\"10\"></textarea>",
"sanitized": "<html><head></head><body>\n\n<textarea type=\"text\" cols=\"50\" rows=\"10\"></textarea></body></html>"
},
{
"data": "<script>\nfunction makePopups(){\n\tfor (i=1;i<6;i++) {\n\t\twindow.open('popup.html','spam'+i,'width=50,height=50');\n\t}\n}\n</script>\n\n<body>\n<a href=\"#\" onclick=\"makePopups()\">Spam</a>",
- "sanitized": "<html><head>\n\n</head><body>\n<a>Spam</a></body></html>"
+ "sanitized": "<html><head>\n\n</head><body>\n<a href=\"#\">Spam</a></body></html>"
},
{
"data": "<html xmlns=\"http://www.w3.org/1999/xhtml\"\nxmlns:svg=\"http://www.w3.org/2000/svg\">\n<body style=\"background:gray\">\n<iframe src=\"http://example.com/\" style=\"width:800px; height:350px; border:none; mask: url(#maskForClickjacking);\"/>\n<svg:svg>\n<svg:mask id=\"maskForClickjacking\" maskUnits=\"objectBoundingBox\" maskContentUnits=\"objectBoundingBox\">\n\t<svg:rect x=\"0.0\" y=\"0.0\" width=\"0.373\" height=\"0.3\" fill=\"white\"/>\n\t<svg:circle cx=\"0.45\" cy=\"0.7\" r=\"0.075\" fill=\"white\"/>\n</svg:mask>\n</svg:svg>\n</body>\n</html>",
"sanitized": "<html><head></head><body>\n\n<svg:svg>\n<svg:mask id=\"maskForClickjacking\" maskUnits=\"objectBoundingBox\" maskContentUnits=\"objectBoundingBox\">\n\t<svg:rect x=\"0.0\" y=\"0.0\" width=\"0.373\" height=\"0.3\" fill=\"white\"/>\n\t<svg:circle cx=\"0.45\" cy=\"0.7\" r=\"0.075\" fill=\"white\"/>\n</svg:mask>\n</svg:svg>\n</body>\n</html></body></html>"
},
{
"data": "<iframe sandbox=\"allow-same-origin allow-forms allow-scripts\" src=\"http://example.org/\"></iframe>",
"sanitized": "<html><head></head><body></body></html>"