From 268b26c194dc869ee779e0e2e6d31afdec5f0c1c Mon Sep 17 00:00:00 2001 From: Thomas Nguyen Date: Tue, 16 Jul 2019 15:03:56 +0000 Subject: [PATCH] Bug 1546334 - Add hash and equals to make ReferrerInfo becomes key of hashtable. r=heycam Differential Revision: https://phabricator.services.mozilla.com/D37577 --HG-- extra : moz-landing-system : lando --- dom/interfaces/security/nsIReferrerInfo.idl | 5 +++ dom/security/ReferrerInfo.cpp | 50 +++++++++++++++++++++ dom/security/ReferrerInfo.h | 9 ++++ 3 files changed, 64 insertions(+) diff --git a/dom/interfaces/security/nsIReferrerInfo.idl b/dom/interfaces/security/nsIReferrerInfo.idl index 77ea55acd198..b8c7831a1d36 100644 --- a/dom/interfaces/security/nsIReferrerInfo.idl +++ b/dom/interfaces/security/nsIReferrerInfo.idl @@ -39,6 +39,11 @@ interface nsIReferrerInfo : nsISerializable [must_use, noscript, nostdcall, notxpcom] URIRef GetComputedReferrer(); + /** + * Returns whether the other referrerInfo is equivalent to this referrerInfo. + */ + boolean equals(in nsIReferrerInfo other); + /** * Initialize method. * @param aReferrerPolicy referrer policy of the created object diff --git a/dom/security/ReferrerInfo.cpp b/dom/security/ReferrerInfo.cpp index 42355e1ff21c..5c528321cb52 100644 --- a/dom/security/ReferrerInfo.cpp +++ b/dom/security/ReferrerInfo.cpp @@ -708,6 +708,42 @@ ReferrerInfo::GetSendReferrer(bool* aSendReferrer) { return NS_OK; } +NS_IMETHODIMP +ReferrerInfo::Equals(nsIReferrerInfo* aOther, bool* aResult) { + NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG); + MOZ_ASSERT(mInitialized); + if (aOther == this) { + *aResult = true; + return NS_OK; + } + + *aResult = false; + ReferrerInfo* other = static_cast(aOther); + MOZ_ASSERT(other->mInitialized); + + if (mPolicy != other->mPolicy || mSendReferrer != other->mSendReferrer || + mOverridePolicyByDefault != other->mOverridePolicyByDefault || + mComputedReferrer != other->mComputedReferrer) { + return NS_OK; + } + + if (!mOriginalReferrer != !other->mOriginalReferrer) { + // One or the other has mOriginalReferrer, but not both... not equal + return NS_OK; + } + + bool originalReferrerEquals; + if (mOriginalReferrer && + (NS_FAILED(mOriginalReferrer->Equals(other->mOriginalReferrer, + &originalReferrerEquals)) || + !originalReferrerEquals)) { + return NS_OK; + } + + *aResult = true; + return NS_OK; +} + already_AddRefed ReferrerInfo::GetComputedReferrer() { if (!mComputedReferrer.isSome() || mComputedReferrer.value().IsEmpty()) { return nullptr; @@ -722,6 +758,20 @@ already_AddRefed ReferrerInfo::GetComputedReferrer() { return result.forget(); } +PLDHashNumber ReferrerInfo::Hash() const { + MOZ_ASSERT(mInitialized); + nsAutoCString originalReferrerSpec; + if (mOriginalReferrer) { + Unused << mOriginalReferrer->GetSpec(originalReferrerSpec); + } + + return mozilla::AddToHash( + mPolicy, mSendReferrer, mOverridePolicyByDefault, + mozilla::HashString(originalReferrerSpec), + mozilla::HashString(mComputedReferrer.isSome() ? mComputedReferrer.value() + : EmptyCString())); +} + NS_IMETHODIMP ReferrerInfo::Init(uint32_t aReferrerPolicy, bool aSendReferrer, nsIURI* aOriginalReferrer) { diff --git a/dom/security/ReferrerInfo.h b/dom/security/ReferrerInfo.h index c4c47a740af2..eaf0b31a3d0f 100644 --- a/dom/security/ReferrerInfo.h +++ b/dom/security/ReferrerInfo.h @@ -13,6 +13,7 @@ #include "mozilla/net/ReferrerPolicy.h" #include "nsReadableUtils.h" #include "mozilla/Maybe.h" +#include "mozilla/HashFunctions.h" #define REFERRERINFOF_CONTRACTID "@mozilla.org/referrer-info;1" // 041a129f-10ce-4bda-a60d-e027a26d5ed0 @@ -31,6 +32,7 @@ class nsIPrincipal; namespace mozilla { class StyleSheet; +class URLAndReferrerInfo; namespace net { class HttpBaseChannel; @@ -187,6 +189,11 @@ class ReferrerInfo : public nsIReferrerInfo { nsIURI* aURI = nullptr, bool privateBrowsing = false); + /** + * Hash function for this object + */ + PLDHashNumber Hash() const; + NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSIREFERRERINFO NS_DECL_NSISERIALIZABLE @@ -348,6 +355,8 @@ class ReferrerInfo : public nsIReferrerInfo { void LogMessageToConsole(nsIHttpChannel* aChannel, const char* aMsg, const nsTArray& aParams) const; + friend class mozilla::URLAndReferrerInfo; + nsCOMPtr mOriginalReferrer; uint32_t mPolicy;