From d3c7ea79a6c2c87b351292b51a6086cf420c7b3e Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Mon, 29 Aug 2016 18:17:26 +0800 Subject: [PATCH] Bug 1297963 - Part 1: Preserve base URI on URLValueData objects. r=emilio MozReview-Commit-ID: EqdYVp9JPsW --- dom/base/nsAttrValue.cpp | 4 ++-- dom/html/nsGenericHTMLElement.cpp | 2 +- layout/style/StyleAnimationValue.cpp | 6 ++++- layout/style/nsCSSValue.cpp | 33 ++++++++++++++++++++-------- layout/style/nsCSSValue.h | 16 ++++++++------ 5 files changed, 41 insertions(+), 20 deletions(-) diff --git a/dom/base/nsAttrValue.cpp b/dom/base/nsAttrValue.cpp index d3469dc01746..98b479fb7ce4 100644 --- a/dom/base/nsAttrValue.cpp +++ b/dom/base/nsAttrValue.cpp @@ -1735,8 +1735,8 @@ nsAttrValue::LoadImage(nsIDocument* aDocument) MiscContainer* cont = GetMiscContainer(); mozilla::css::URLValue* url = cont->mValue.mURL; mozilla::css::ImageValue* image = - new css::ImageValue(url->GetURI(), url->mString, url->mReferrer, - url->mOriginPrincipal, aDocument); + new css::ImageValue(url->GetURI(), url->mString, url->mBaseURI, + url->mReferrer, url->mOriginPrincipal, aDocument); NS_ADDREF(image); cont->mValue.mImage = image; diff --git a/dom/html/nsGenericHTMLElement.cpp b/dom/html/nsGenericHTMLElement.cpp index 05a94e90416d..268379a5171c 100644 --- a/dom/html/nsGenericHTMLElement.cpp +++ b/dom/html/nsGenericHTMLElement.cpp @@ -981,7 +981,7 @@ nsGenericHTMLElement::ParseBackgroundAttribute(int32_t aNamespaceID, } mozilla::css::URLValue *url = - new mozilla::css::URLValue(uri, buffer, doc->GetDocumentURI(), + new mozilla::css::URLValue(uri, buffer, baseURI, doc->GetDocumentURI(), NodePrincipal()); aResult.SetTo(url, &aValue); return true; diff --git a/layout/style/StyleAnimationValue.cpp b/layout/style/StyleAnimationValue.cpp index ffcf558f18a8..92f4350ba7b4 100644 --- a/layout/style/StyleAnimationValue.cpp +++ b/layout/style/StyleAnimationValue.cpp @@ -291,9 +291,13 @@ FragmentOrURLToURLValue(FragmentOrURL* aUrl, nsIDocument* aDoc) nsString path; aUrl->GetSourceString(path); RefPtr uriStringBuffer = nsCSSValue::BufferFromString(path); + // XXXheycam We should store URLValue objects inside FragmentOrURLs so that + // we can extract the original base URI, referrer and principal to pass in + // here. RefPtr result = new mozilla::css::URLValue(aUrl->GetSourceURL(), uriStringBuffer, - aDoc->GetDocumentURI(), aDoc->NodePrincipal()); + aUrl->GetSourceURL(), aDoc->GetDocumentURI(), + aDoc->NodePrincipal()); return result.forget(); } diff --git a/layout/style/nsCSSValue.cpp b/layout/style/nsCSSValue.cpp index 7112dd4b8a44..e019976855c5 100644 --- a/layout/style/nsCSSValue.cpp +++ b/layout/style/nsCSSValue.cpp @@ -761,6 +761,7 @@ void nsCSSValue::StartImageLoad(nsIDocument* aDocument) const mozilla::css::ImageValue* image = new mozilla::css::ImageValue(mValue.mURL->GetURI(), mValue.mURL->mString, + mValue.mURL->mBaseURI, mValue.mURL->mReferrer, mValue.mURL->mOriginPrincipal, aDocument); @@ -2592,17 +2593,21 @@ nsCSSValue::Array::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) cons css::URLValueData::URLValueData(already_AddRefed> aURI, nsStringBuffer* aString, + already_AddRefed> aBaseURI, already_AddRefed> aReferrer, already_AddRefed> aOriginPrincipal) : mURI(Move(aURI)) + , mBaseURI(Move(aBaseURI)) , mString(aString) , mReferrer(Move(aReferrer)) , mOriginPrincipal(Move(aOriginPrincipal)) , mURIResolved(true) , mLocalURLFlag(IsLocalRefURL(aString)) { - MOZ_ASSERT(mOriginPrincipal, "Must have an origin principal"); + MOZ_ASSERT(mString); + MOZ_ASSERT(mBaseURI); + MOZ_ASSERT(mOriginPrincipal); } css::URLValueData::URLValueData(nsStringBuffer* aString, @@ -2610,14 +2615,16 @@ css::URLValueData::URLValueData(nsStringBuffer* aString, already_AddRefed> aReferrer, already_AddRefed> aOriginPrincipal) - : mURI(Move(aBaseURI)) + : mBaseURI(Move(aBaseURI)) , mString(aString) , mReferrer(Move(aReferrer)) , mOriginPrincipal(Move(aOriginPrincipal)) , mURIResolved(false) , mLocalURLFlag(IsLocalRefURL(aString)) { - MOZ_ASSERT(mOriginPrincipal, "Must have an origin principal"); + MOZ_ASSERT(aString); + MOZ_ASSERT(mBaseURI); + MOZ_ASSERT(mOriginPrincipal); } bool @@ -2633,6 +2640,9 @@ css::URLValueData::operator==(const URLValueData& aOther) const (mURI && aOther.mURI && NS_SUCCEEDED(mURI->Equals(aOther.mURI, &eq)) && eq)) && + (mBaseURI == aOther.mBaseURI || + (NS_SUCCEEDED(self.mBaseURI.get()->Equals(other.mBaseURI.get(), &eq)) && + eq)) && (mOriginPrincipal == aOther.mOriginPrincipal || self.mOriginPrincipal.get()->Equals(other.mOriginPrincipal.get())) && mLocalURLFlag == aOther.mLocalURLFlag; @@ -2671,14 +2681,16 @@ css::URLValueData::URIEquals(const URLValueData& aOther) const nsIURI* css::URLValueData::GetURI() const { + MOZ_ASSERT(NS_IsMainThread()); + if (!mURIResolved) { - mURIResolved = true; - // Be careful to not null out mURI before we've passed it as the base URI + MOZ_ASSERT(!mURI); nsCOMPtr newURI; NS_NewURI(getter_AddRefs(newURI), NS_ConvertUTF16toUTF8(nsCSSValue::GetBufferValue(mString)), - nullptr, mURI); + nullptr, const_cast(mBaseURI.get())); mURI = new PtrHolder(newURI.forget()); + mURIResolved = true; } return mURI; @@ -2708,10 +2720,11 @@ URLValue::URLValue(nsStringBuffer* aString, nsIURI* aBaseURI, nsIURI* aReferrer, MOZ_ASSERT(NS_IsMainThread()); } -URLValue::URLValue(nsIURI* aURI, nsStringBuffer* aString, nsIURI* aReferrer, - nsIPrincipal* aOriginPrincipal) +URLValue::URLValue(nsIURI* aURI, nsStringBuffer* aString, nsIURI* aBaseURI, + nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal) : URLValueData(do_AddRef(new PtrHolder(aURI)), aString, + do_AddRef(new PtrHolder(aBaseURI)), do_AddRef(new PtrHolder(aReferrer)), do_AddRef(new PtrHolder(aOriginPrincipal))) { @@ -2731,10 +2744,12 @@ css::URLValue::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const } css::ImageValue::ImageValue(nsIURI* aURI, nsStringBuffer* aString, - nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal, + nsIURI* aBaseURI, nsIURI* aReferrer, + nsIPrincipal* aOriginPrincipal, nsIDocument* aDocument) : URLValueData(do_AddRef(new PtrHolder(aURI)), aString, + do_AddRef(new PtrHolder(aBaseURI, false)), do_AddRef(new PtrHolder(aReferrer)), do_AddRef(new PtrHolder(aOriginPrincipal))) { diff --git a/layout/style/nsCSSValue.h b/layout/style/nsCSSValue.h index 2387abef152c..3b4ab440ed49 100644 --- a/layout/style/nsCSSValue.h +++ b/layout/style/nsCSSValue.h @@ -106,6 +106,7 @@ struct URLValueData // Construct with the actual URI. URLValueData(already_AddRefed> aURI, nsStringBuffer* aString, + already_AddRefed> aBaseURI, already_AddRefed> aReferrer, already_AddRefed> aOriginPrincipal); @@ -128,11 +129,11 @@ struct URLValueData bool GetLocalURLFlag() const { return mLocalURLFlag; } private: - // If mURIResolved is false, mURI stores the base URI. - // If mURIResolved is true, mURI stores the URI we resolve to; this may be - // null if the URI is invalid. + // mURI stores the lazily resolved URI. This may be null if the URI is + // invalid, even once resolved. mutable PtrHandle mURI; public: + PtrHandle mBaseURI; RefPtr mString; PtrHandle mReferrer; PtrHandle mOriginPrincipal; @@ -151,8 +152,8 @@ struct URLValue : public URLValueData // These two constructors are safe to call only on the main thread. URLValue(nsStringBuffer* aString, nsIURI* aBaseURI, nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal); - URLValue(nsIURI* aURI, nsStringBuffer* aString, nsIURI* aReferrer, - nsIPrincipal* aOriginPrincipal); + URLValue(nsIURI* aURI, nsStringBuffer* aString, nsIURI* aBaseURI, + nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal); // This constructor is safe to call from any thread. URLValue(nsStringBuffer* aString, @@ -182,8 +183,9 @@ struct ImageValue : public URLValueData // aString must not be null. // // This constructor is only safe to call from the main thread. - ImageValue(nsIURI* aURI, nsStringBuffer* aString, nsIURI* aReferrer, - nsIPrincipal* aOriginPrincipal, nsIDocument* aDocument); + ImageValue(nsIURI* aURI, nsStringBuffer* aString, nsIURI* aBaseURI, + nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal, + nsIDocument* aDocument); ImageValue(const ImageValue&) = delete; ImageValue& operator=(const ImageValue&) = delete;