diff --git a/image/ImageCacheKey.cpp b/image/ImageCacheKey.cpp index 8366141d6686..1f4b2e64c2ae 100644 --- a/image/ImageCacheKey.cpp +++ b/image/ImageCacheKey.cpp @@ -45,8 +45,11 @@ BlobSerial(ImageURL* aURI) return Nothing(); } -ImageCacheKey::ImageCacheKey(nsIURI* aURI, nsIDocument* aDocument) +ImageCacheKey::ImageCacheKey(nsIURI* aURI, + const PrincipalOriginAttributes& aAttrs, + nsIDocument* aDocument) : mURI(new ImageURL(aURI)) + , mOriginAttributes(aAttrs) , mControlledDocument(GetControlledDocumentToken(aDocument)) , mIsChrome(URISchemeIs(mURI, "chrome")) { @@ -56,11 +59,14 @@ ImageCacheKey::ImageCacheKey(nsIURI* aURI, nsIDocument* aDocument) mBlobSerial = BlobSerial(mURI); } - mHash = ComputeHash(mURI, mBlobSerial, mControlledDocument); + mHash = ComputeHash(mURI, mBlobSerial, mOriginAttributes, mControlledDocument); } -ImageCacheKey::ImageCacheKey(ImageURL* aURI, nsIDocument* aDocument) +ImageCacheKey::ImageCacheKey(ImageURL* aURI, + const PrincipalOriginAttributes& aAttrs, + nsIDocument* aDocument) : mURI(aURI) + , mOriginAttributes(aAttrs) , mControlledDocument(GetControlledDocumentToken(aDocument)) , mIsChrome(URISchemeIs(mURI, "chrome")) { @@ -70,12 +76,13 @@ ImageCacheKey::ImageCacheKey(ImageURL* aURI, nsIDocument* aDocument) mBlobSerial = BlobSerial(mURI); } - mHash = ComputeHash(mURI, mBlobSerial, mControlledDocument); + mHash = ComputeHash(mURI, mBlobSerial, mOriginAttributes, mControlledDocument); } ImageCacheKey::ImageCacheKey(const ImageCacheKey& aOther) : mURI(aOther.mURI) , mBlobSerial(aOther.mBlobSerial) + , mOriginAttributes(aOther.mOriginAttributes) , mControlledDocument(aOther.mControlledDocument) , mHash(aOther.mHash) , mIsChrome(aOther.mIsChrome) @@ -84,6 +91,7 @@ ImageCacheKey::ImageCacheKey(const ImageCacheKey& aOther) ImageCacheKey::ImageCacheKey(ImageCacheKey&& aOther) : mURI(Move(aOther.mURI)) , mBlobSerial(Move(aOther.mBlobSerial)) + , mOriginAttributes(aOther.mOriginAttributes) , mControlledDocument(aOther.mControlledDocument) , mHash(aOther.mHash) , mIsChrome(aOther.mIsChrome) @@ -96,6 +104,10 @@ ImageCacheKey::operator==(const ImageCacheKey& aOther) const if (mControlledDocument != aOther.mControlledDocument) { return false; } + // The origin attributes always have to match. + if (mOriginAttributes != aOther.mOriginAttributes) { + return false; + } if (mBlobSerial || aOther.mBlobSerial) { // If at least one of us has a blob serial, just compare the blob serial and // the ref portion of the URIs. @@ -116,12 +128,16 @@ ImageCacheKey::Spec() const /* static */ uint32_t ImageCacheKey::ComputeHash(ImageURL* aURI, const Maybe& aBlobSerial, + const PrincipalOriginAttributes& aAttrs, void* aControlledDocument) { // Since we frequently call Hash() several times in a row on the same // ImageCacheKey, as an optimization we compute our hash once and store it. nsPrintfCString ptr("%p", aControlledDocument); + nsAutoCString suffix; + aAttrs.CreateSuffix(suffix); + if (aBlobSerial) { // For blob URIs, we hash the serial number of the underlying blob, so that // different blob URIs which point to the same blob share a cache entry. We @@ -130,13 +146,13 @@ ImageCacheKey::ComputeHash(ImageURL* aURI, // the same. nsAutoCString ref; aURI->GetRef(ref); - return HashGeneric(*aBlobSerial, HashString(ref + ptr)); + return HashGeneric(*aBlobSerial, HashString(ref + suffix + ptr)); } // For non-blob URIs, we hash the URI spec. nsAutoCString spec; aURI->GetSpec(spec); - return HashString(spec + ptr); + return HashString(spec + suffix + ptr); } /* static */ void* diff --git a/image/ImageCacheKey.h b/image/ImageCacheKey.h index 16a5b1d79ecb..e1cdd381c2c0 100644 --- a/image/ImageCacheKey.h +++ b/image/ImageCacheKey.h @@ -10,6 +10,7 @@ #ifndef mozilla_image_src_ImageCacheKey_h #define mozilla_image_src_ImageCacheKey_h +#include "mozilla/BasePrincipal.h" #include "mozilla/Maybe.h" #include "mozilla/RefPtr.h" @@ -32,8 +33,10 @@ class ImageURL; class ImageCacheKey final { public: - ImageCacheKey(nsIURI* aURI, nsIDocument* aDocument); - ImageCacheKey(ImageURL* aURI, nsIDocument* aDocument); + ImageCacheKey(nsIURI* aURI, const PrincipalOriginAttributes& aAttrs, + nsIDocument* aDocument); + ImageCacheKey(ImageURL* aURI, const PrincipalOriginAttributes& aAttrs, + nsIDocument* aDocument); ImageCacheKey(const ImageCacheKey& aOther); ImageCacheKey(ImageCacheKey&& aOther); @@ -54,11 +57,13 @@ public: private: static uint32_t ComputeHash(ImageURL* aURI, const Maybe& aBlobSerial, + const PrincipalOriginAttributes& aAttrs, void* aControlledDocument); static void* GetControlledDocumentToken(nsIDocument* aDocument); RefPtr mURI; Maybe mBlobSerial; + PrincipalOriginAttributes mOriginAttributes; void* mControlledDocument; uint32_t mHash; bool mIsChrome; diff --git a/image/imgLoader.cpp b/image/imgLoader.cpp index 3d1530fa47e4..fd20e96aabb9 100644 --- a/image/imgLoader.cpp +++ b/image/imgLoader.cpp @@ -1352,7 +1352,16 @@ imgLoader::FindEntryProperties(nsIURI* uri, *_retval = nullptr; nsCOMPtr doc = do_QueryInterface(aDOMDoc); - ImageCacheKey key(uri, doc); + + PrincipalOriginAttributes attrs; + if (doc) { + nsCOMPtr principal = doc->NodePrincipal(); + if (principal) { + attrs = BasePrincipal::Cast(principal)->OriginAttributesRef(); + } + } + + ImageCacheKey key(uri, attrs, doc); imgCacheTable& cache = GetCache(key); RefPtr entry; @@ -2110,7 +2119,11 @@ imgLoader::LoadImage(nsIURI* aURI, // XXX For now ignore aCacheKey. We will need it in the future // for correctly dealing with image load requests that are a result // of post data. - ImageCacheKey key(aURI, aLoadingDocument); + PrincipalOriginAttributes attrs; + if (aLoadingPrincipal) { + attrs = BasePrincipal::Cast(aLoadingPrincipal)->OriginAttributesRef(); + } + ImageCacheKey key(aURI, attrs, aLoadingDocument); imgCacheTable& cache = GetCache(key); if (cache.Get(key, getter_AddRefs(entry)) && entry) { @@ -2314,7 +2327,16 @@ imgLoader::LoadImageWithChannel(nsIChannel* channel, nsCOMPtr uri; channel->GetURI(getter_AddRefs(uri)); nsCOMPtr doc = do_QueryInterface(aCX); - ImageCacheKey key(uri, doc); + + NS_ENSURE_TRUE(channel, NS_ERROR_FAILURE); + nsCOMPtr loadInfo = channel->GetLoadInfo(); + + PrincipalOriginAttributes attrs; + if (loadInfo) { + attrs.InheritFromNecko(loadInfo->GetOriginAttributes()); + } + + ImageCacheKey key(uri, attrs, doc); nsLoadFlags requestFlags = nsIRequest::LOAD_NORMAL; channel->GetLoadFlags(&requestFlags); @@ -2416,7 +2438,7 @@ imgLoader::LoadImageWithChannel(nsIChannel* channel, // constructed above with the *current URI* and not the *original URI*. I'm // pretty sure this is a bug, and it's preventing us from ever getting a // cache hit in LoadImageWithChannel when redirects are involved. - ImageCacheKey originalURIKey(originalURI, doc); + ImageCacheKey originalURIKey(originalURI, attrs, doc); // Default to doing a principal check because we don't know who // started that load and whether their principal ended up being