$OpenBSD$ index 8e0d11f..853f86c 100644 --- image/src/imgLoader.cpp.orig Fri Feb 20 15:40:37 2015 +++ image/src/imgLoader.cpp Fri Feb 20 15:40:37 2015 @@ -30,6 +30,7 @@ #include "nsCRT.h" #include "nsIDocument.h" #include "nsINetworkSeer.h" +#include "nsIConsoleService.h" #include "nsIApplicationCache.h" #include "nsIApplicationCacheContainer.h" @@ -392,7 +393,7 @@ static nsresult NewImageChannel(nsIChannel **aResult, // aLoadingPrincipal and false otherwise. bool *aForcePrincipalCheckForCacheEntry, nsIURI *aURI, - nsIURI *aInitialDocumentURI, + nsIURI *aFirstPartyIsolationURI, nsIURI *aReferringURI, nsILoadGroup *aLoadGroup, const nsCString& aAcceptHeader, @@ -443,7 +444,7 @@ static nsresult NewImageChannel(nsIChannel **aResult, nsCOMPtr httpChannelInternal = do_QueryInterface(newHttpChannel); NS_ENSURE_TRUE(httpChannelInternal, NS_ERROR_UNEXPECTED); - httpChannelInternal->SetDocumentURI(aInitialDocumentURI); + httpChannelInternal->SetDocumentURI(aFirstPartyIsolationURI); newHttpChannel->SetReferrer(aReferringURI); } @@ -729,6 +730,8 @@ double imgLoader::sCacheTimeWeight; uint32_t imgLoader::sCacheMaxSize; imgMemoryReporter* imgLoader::sMemReporter; +nsCOMPtr imgLoader::sThirdPartyUtilSvc; + NS_IMPL_ISUPPORTS(imgLoader, imgILoader, nsIContentSniffer, imgICache, nsISupportsWeakReference, nsIObserver) static imgLoader* gSingleton = nullptr; @@ -854,6 +857,8 @@ void imgLoader::GlobalInit() sMemReporter = new imgMemoryReporter(); RegisterStrongMemoryReporter(sMemReporter); RegisterImagesContentUsedUncompressedDistinguishedAmount(imgMemoryReporter::ImagesContentUsedUncompressedDistinguishedAmount); + + sThirdPartyUtilSvc = do_GetService(THIRDPARTYUTIL_CONTRACTID); } nsresult imgLoader::InitCache() @@ -946,34 +951,62 @@ NS_IMETHODIMP imgLoader::ClearCache(bool chrome) /* void removeEntry(in nsIURI uri); */ NS_IMETHODIMP imgLoader::RemoveEntry(nsIURI *uri) { - if (RemoveFromCache(uri)) + if (RemoveMatchingUrlsFromCache(uri)) return NS_OK; return NS_ERROR_NOT_AVAILABLE; } +static PLDHashOperator EnumAllEntries(const nsACString&, + nsRefPtr &aData, + void *data) +{ + nsTArray > *entries = + reinterpret_cast > *>(data); + + entries->AppendElement(aData); + + return PL_DHASH_NEXT; +} + /* imgIRequest findEntry(in nsIURI uri); */ NS_IMETHODIMP imgLoader::FindEntryProperties(nsIURI *uri, nsIProperties **_retval) { nsRefPtr entry; - nsAutoCString spec; imgCacheTable &cache = GetCache(uri); - - uri->GetSpec(spec); *_retval = nullptr; - if (cache.Get(spec, getter_AddRefs(entry)) && entry) { - if (mCacheTracker && entry->HasNoProxies()) - mCacheTracker->MarkUsed(entry); + // We must traverse the whole cache in O(N) looking for the first + // matching URI. + // + // TODO: For now, it's ok to pick at random here. The images should be + // identical unless there is a cache-tracking attack. And even if they + // are not identical due to attack, this code is only used for save + // dialogs at this point, so no differentiating info is leaked to + // content. + nsTArray > entries; + cache.Enumerate(EnumAllEntries, &entries); - nsRefPtr request = entry->GetRequest(); + for (uint32_t i = 0; i < entries.Length(); ++i) { + bool isEqual = false; + + nsRefPtr request = entries[i]->GetRequest(); if (request) { - *_retval = request->Properties(); - NS_ADDREF(*_retval); + request->mURI->Equals(uri, &isEqual); + if (isEqual) { + if (mCacheTracker && entries[i]->HasNoProxies()) { + mCacheTracker->MarkUsed(entries[i]); + } + *_retval = request->Properties(); + NS_ADDREF(*_retval); + break; + } } } - - return NS_OK; + if (*_retval) { + return NS_OK; + } + return NS_ERROR_NOT_AVAILABLE; } void imgLoader::Shutdown() @@ -981,6 +1014,7 @@ void imgLoader::Shutdown() NS_IF_RELEASE(gSingleton); NS_IF_RELEASE(gPBSingleton); NS_RELEASE(gCacheObserver); + sThirdPartyUtilSvc = nullptr; } nsresult imgLoader::ClearChromeImageCache() @@ -999,20 +1033,17 @@ void imgLoader::MinimizeCaches() EvictEntries(mChromeCacheQueue); } -bool imgLoader::PutIntoCache(nsIURI *key, imgCacheEntry *entry) +bool imgLoader::PutIntoCache(nsAutoCString key, imgCacheEntry *entry) { - imgCacheTable &cache = GetCache(key); - - nsAutoCString spec; - key->GetSpec(spec); - - LOG_STATIC_FUNC_WITH_PARAM(GetImgLog(), "imgLoader::PutIntoCache", "uri", spec.get()); + LOG_STATIC_FUNC_WITH_PARAM(GetImgLog(), "imgLoader::PutIntoCache", "uri", key.get()); + imgCacheTable &cache = GetCache(entry->mRequest->mURI); + imgCacheQueue &queue = GetCacheQueue(entry->mRequest->mURI); // Check to see if this request already exists in the cache and is being // loaded on a different thread. If so, don't allow this entry to be added to // the cache. nsRefPtr tmpCacheEntry; - if (cache.Get(spec, getter_AddRefs(tmpCacheEntry)) && tmpCacheEntry) { + if (cache.Get(key, getter_AddRefs(tmpCacheEntry)) && tmpCacheEntry) { PR_LOG(GetImgLog(), PR_LOG_DEBUG, ("[this=%p] imgLoader::PutIntoCache -- Element already in the cache", nullptr)); nsRefPtr tmpRequest = tmpCacheEntry->GetRequest(); @@ -1022,13 +1053,13 @@ bool imgLoader::PutIntoCache(nsIURI *key, imgCacheEntry *entry) PR_LOG(GetImgLog(), PR_LOG_DEBUG, ("[this=%p] imgLoader::PutIntoCache -- Replacing cached element", nullptr)); - RemoveFromCache(key); + RemoveFromCache(key, cache, queue); } else { PR_LOG(GetImgLog(), PR_LOG_DEBUG, ("[this=%p] imgLoader::PutIntoCache -- Element NOT already in the cache", nullptr)); } - cache.Put(spec, entry); + cache.Put(key, entry); // We can be called to resurrect an evicted entry. if (entry->Evicted()) @@ -1043,7 +1074,6 @@ bool imgLoader::PutIntoCache(nsIURI *key, imgCacheEntry *entry) addrv = mCacheTracker->AddObject(entry); if (NS_SUCCEEDED(addrv)) { - imgCacheQueue &queue = GetCacheQueue(key); queue.Push(entry); } } @@ -1054,11 +1084,11 @@ bool imgLoader::PutIntoCache(nsIURI *key, imgCacheEntry *entry) return true; } -bool imgLoader::SetHasNoProxies(ImageURL *key, imgCacheEntry *entry) +bool imgLoader::SetHasNoProxies(ImageURL *imgURI, imgCacheEntry *entry) { #if defined(PR_LOGGING) nsAutoCString spec; - key->GetSpec(spec); + imgURI->GetSpec(spec); LOG_STATIC_FUNC_WITH_PARAM(GetImgLog(), "imgLoader::SetHasNoProxies", "uri", spec.get()); #endif @@ -1066,7 +1096,7 @@ bool imgLoader::SetHasNoProxies(ImageURL *key, imgCacheEntry *entry) if (entry->Evicted()) return false; - imgCacheQueue &queue = GetCacheQueue(key); + imgCacheQueue &queue = GetCacheQueue(imgURI); nsresult addrv = NS_OK; @@ -1078,26 +1108,27 @@ bool imgLoader::SetHasNoProxies(ImageURL *key, imgCacheEntry *entry) entry->SetHasNoProxies(true); } - imgCacheTable &cache = GetCache(key); + imgCacheTable &cache = GetCache(imgURI); CheckCacheLimits(cache, queue); return true; } -bool imgLoader::SetHasProxies(ImageURL *key) +bool imgLoader::SetHasProxies(nsIURI *firstPartyIsolationURI, ImageURL *imgURI) { VerifyCacheSizes(); - imgCacheTable &cache = GetCache(key); + imgCacheTable &cache = GetCache(imgURI); nsAutoCString spec; - key->GetSpec(spec); + imgURI->GetSpec(spec); LOG_STATIC_FUNC_WITH_PARAM(GetImgLog(), "imgLoader::SetHasProxies", "uri", spec.get()); + nsAutoCString key = GetCacheKey(firstPartyIsolationURI, imgURI, nullptr); nsRefPtr entry; - if (cache.Get(spec, getter_AddRefs(entry)) && entry && entry->HasNoProxies()) { - imgCacheQueue &queue = GetCacheQueue(key); + if (cache.Get(key, getter_AddRefs(entry)) && entry && entry->HasNoProxies()) { + imgCacheQueue &queue = GetCacheQueue(imgURI); queue.Remove(entry); if (mCacheTracker) @@ -1149,7 +1180,7 @@ void imgLoader::CheckCacheLimits(imgCacheTable &cache, imgCacheQueue &queue) bool imgLoader::ValidateRequestWithNewChannel(imgRequest *request, nsIURI *aURI, - nsIURI *aInitialDocumentURI, + nsIURI *aFirstPartyIsolationURI, nsIURI *aReferrerURI, nsILoadGroup *aLoadGroup, imgINotificationObserver *aObserver, @@ -1199,7 +1230,7 @@ bool imgLoader::ValidateRequestWithNewChannel(imgRequest *request, rv = NewImageChannel(getter_AddRefs(newChannel), &forcePrincipalCheck, aURI, - aInitialDocumentURI, + aFirstPartyIsolationURI, aReferrerURI, aLoadGroup, mAcceptHeader, @@ -1262,7 +1293,7 @@ bool imgLoader::ValidateRequestWithNewChannel(imgRequest *request, // Add the proxy without notifying hvc->AddProxy(proxy); - mozilla::net::SeerLearn(aURI, aInitialDocumentURI, + mozilla::net::SeerLearn(aURI, aFirstPartyIsolationURI, nsINetworkSeer::LEARN_LOAD_SUBRESOURCE, aLoadGroup); rv = newChannel->AsyncOpen(listener, nullptr); @@ -1275,7 +1306,7 @@ bool imgLoader::ValidateRequestWithNewChannel(imgRequest *request, bool imgLoader::ValidateEntry(imgCacheEntry *aEntry, nsIURI *aURI, - nsIURI *aInitialDocumentURI, + nsIURI *aFirstPartyIsolationURI, nsIURI *aReferrerURI, nsILoadGroup *aLoadGroup, imgINotificationObserver *aObserver, @@ -1386,7 +1417,7 @@ bool imgLoader::ValidateEntry(imgCacheEntry *aEntry, if (validateRequest && aCanMakeNewChannel) { LOG_SCOPE(GetImgLog(), "imgLoader::ValidateRequest |cache hit| must validate"); - return ValidateRequestWithNewChannel(request, aURI, aInitialDocumentURI, + return ValidateRequestWithNewChannel(request, aURI, aFirstPartyIsolationURI, aReferrerURI, aLoadGroup, aObserver, aCX, aLoadFlags, aProxyRequest, aPolicy, aLoadingPrincipal, aCORSMode); @@ -1395,43 +1426,39 @@ bool imgLoader::ValidateEntry(imgCacheEntry *aEntry, return !validateRequest; } -bool imgLoader::RemoveFromCache(nsIURI *aKey) +bool imgLoader::RemoveMatchingUrlsFromCache(nsIURI *aImgURI) { MOZ_ASSERT(NS_IsMainThread(), "Cannot use nsIURI off main thread!"); - if (!aKey) return false; - - imgCacheTable &cache = GetCache(aKey); - imgCacheQueue &queue = GetCacheQueue(aKey); + if (!aImgURI) return false; - nsAutoCString spec; - aKey->GetSpec(spec); - - return RemoveFromCache(spec, cache, queue); -} + bool rv = true; + imgCacheTable &cache = GetCache(aImgURI); -bool imgLoader::RemoveFromCache(ImageURL *aKey) -{ - if (!aKey) return false; - - imgCacheTable &cache = GetCache(aKey); - imgCacheQueue &queue = GetCacheQueue(aKey); + // We have to make a temporary, since RemoveFromCache removes the element + // from the queue, invalidating iterators. + nsTArray > entries; + cache.Enumerate(EnumAllEntries, &entries); + for (uint32_t i = 0; i < entries.Length(); ++i) { + bool isEqual = false; - nsAutoCString spec; - aKey->GetSpec(spec); + entries[i]->mRequest->mURI->Equals(aImgURI, &isEqual); + if (isEqual && !RemoveFromCache(entries[i])) + rv = false; + } - return RemoveFromCache(spec, cache, queue); + return rv; } -bool imgLoader::RemoveFromCache(nsCString& spec, +bool imgLoader::RemoveFromCache(nsAutoCString key, imgCacheTable &cache, imgCacheQueue &queue) { - LOG_STATIC_FUNC_WITH_PARAM(GetImgLog(), "imgLoader::RemoveFromCache", "uri", spec.get()); + if (key.IsEmpty()) return false; nsRefPtr entry; - if (cache.Get(spec, getter_AddRefs(entry)) && entry) { - cache.Remove(spec); + if (cache.Get(key, getter_AddRefs(entry)) && entry) { + cache.Remove(key); NS_ABORT_IF_FALSE(!entry->Evicted(), "Evicting an already-evicted cache entry!"); @@ -1459,12 +1486,12 @@ bool imgLoader::RemoveFromCache(imgCacheEntry *entry) nsRefPtr request = entry->GetRequest(); if (request) { - nsRefPtr key; - if (NS_SUCCEEDED(request->GetURI(getter_AddRefs(key))) && key) { - imgCacheTable &cache = GetCache(key); - imgCacheQueue &queue = GetCacheQueue(key); - nsAutoCString spec; - key->GetSpec(spec); + nsRefPtr imgURI; + if (NS_SUCCEEDED(request->GetURI(getter_AddRefs(imgURI))) && imgURI) { + nsCOMPtr firstPartyIsolationURI = request->mFirstPartyIsolationURI; + imgCacheTable &cache = GetCache(imgURI); + imgCacheQueue &queue = GetCacheQueue(imgURI); + nsAutoCString spec = GetCacheKey(firstPartyIsolationURI, imgURI, nullptr); LOG_STATIC_FUNC_WITH_PARAM(GetImgLog(), "imgLoader::RemoveFromCache", "entry's uri", spec.get()); @@ -1487,32 +1514,21 @@ bool imgLoader::RemoveFromCache(imgCacheEntry *entry) return false; } -static PLDHashOperator EnumEvictEntries(const nsACString&, - nsRefPtr &aData, - void *data) -{ - nsTArray > *entries = - reinterpret_cast > *>(data); - - entries->AppendElement(aData); - - return PL_DHASH_NEXT; -} - nsresult imgLoader::EvictEntries(imgCacheTable &aCacheToClear) { + nsresult rv = NS_OK; LOG_STATIC_FUNC(GetImgLog(), "imgLoader::EvictEntries table"); // We have to make a temporary, since RemoveFromCache removes the element // from the queue, invalidating iterators. nsTArray > entries; - aCacheToClear.Enumerate(EnumEvictEntries, &entries); + aCacheToClear.Enumerate(EnumAllEntries, &entries); for (uint32_t i = 0; i < entries.Length(); ++i) if (!RemoveFromCache(entries[i])) - return NS_ERROR_FAILURE; + rv = NS_ERROR_FAILURE; - return NS_OK; + return rv; } nsresult imgLoader::EvictEntries(imgCacheQueue &aQueueToClear) @@ -1569,11 +1585,10 @@ NS_IMETHODIMP imgLoader::LoadImageXPCOM(nsIURI *aURI, } - -/* imgIRequest loadImage(in nsIURI aURI, in nsIURI aInitialDocumentURL, in nsIURI aReferrerURI, in nsIPrincipal aLoadingPrincipal, in nsILoadGroup aLoadGroup, in imgINotificationObserver aObserver, in nsISupports aCX, in nsLoadFlags aLoadFlags, in nsISupports cacheKey, in nsIChannelPolicy channelPolicy); */ +/* imgIRequest loadImage (in nsIURI aURI, in nsIURI aUrlBarURI, in nsIPrincipal loadingPrincipal, in nsILoadGroup aLoadGroup, in imgIDecoderObserver aObserver, in nsISupports aCX, in nsLoadFlags aLoadFlags, in nsISupports cacheKey, in imgIRequest aRequest); */ nsresult imgLoader::LoadImage(nsIURI *aURI, - nsIURI *aInitialDocumentURI, + nsIURI *aFirstPartyIsolationURI, nsIURI *aReferrerURI, nsIPrincipal* aLoadingPrincipal, nsILoadGroup *aLoadGroup, @@ -1592,8 +1607,9 @@ nsresult imgLoader::LoadImage(nsIURI *aURI, if (!aURI) return NS_ERROR_NULL_POINTER; - nsAutoCString spec; - aURI->GetSpec(spec); + bool isIsolated = false; + nsAutoCString spec = GetCacheKey(aFirstPartyIsolationURI, aURI, &isIsolated); + LOG_SCOPE_WITH_PARAM(GetImgLog(), "imgLoader::LoadImage", "aURI", spec.get()); *_retval = nullptr; @@ -1659,7 +1675,7 @@ nsresult imgLoader::LoadImage(nsIURI *aURI, imgCacheTable &cache = GetCache(aURI); if (cache.Get(spec, getter_AddRefs(entry)) && entry) { - if (ValidateEntry(entry, aURI, aInitialDocumentURI, aReferrerURI, + if (ValidateEntry(entry, aURI, aFirstPartyIsolationURI, aReferrerURI, aLoadGroup, aObserver, aCX, requestFlags, true, _retval, aPolicy, aLoadingPrincipal, corsmode)) { request = entry->GetRequest(); @@ -1698,7 +1714,7 @@ nsresult imgLoader::LoadImage(nsIURI *aURI, rv = NewImageChannel(getter_AddRefs(newChannel), &forcePrincipalCheck, aURI, - aInitialDocumentURI, + aFirstPartyIsolationURI, aReferrerURI, aLoadGroup, mAcceptHeader, @@ -1717,7 +1733,7 @@ nsresult imgLoader::LoadImage(nsIURI *aURI, nsCOMPtr channelLoadGroup; newChannel->GetLoadGroup(getter_AddRefs(channelLoadGroup)); - request->Init(aURI, aURI, channelLoadGroup, newChannel, entry, aCX, + request->Init(aURI, aURI, aFirstPartyIsolationURI, channelLoadGroup, newChannel, entry, aCX, aLoadingPrincipal, corsmode); // Add the initiator type for this image load @@ -1761,7 +1777,7 @@ nsresult imgLoader::LoadImage(nsIURI *aURI, PR_LOG(GetImgLog(), PR_LOG_DEBUG, ("[this=%p] imgLoader::LoadImage -- Calling channel->AsyncOpen()\n", this)); - mozilla::net::SeerLearn(aURI, aInitialDocumentURI, + mozilla::net::SeerLearn(aURI, aFirstPartyIsolationURI, nsINetworkSeer::LEARN_LOAD_SUBRESOURCE, aLoadGroup); nsresult openRes = newChannel->AsyncOpen(listener, nullptr); @@ -1774,8 +1790,8 @@ nsresult imgLoader::LoadImage(nsIURI *aURI, return openRes; } - // Try to add the new request into the cache. - PutIntoCache(aURI, entry); + if (isIsolated) // Try to add the new request into the cache. + PutIntoCache(spec, entry); } else { LOG_MSG_WITH_PARAM(GetImgLog(), "imgLoader::LoadImage |cache hit|", "request", request); @@ -1835,6 +1851,41 @@ nsresult imgLoader::LoadImage(nsIURI *aURI, return NS_OK; } +nsAutoCString imgLoader::GetCacheKey(nsIURI *firstPartyIsolationURI, ImageURL *imgURI, + bool *isIsolated) +{ + NS_ASSERTION(imgURI, "imgLoader::GetCacheKey -- NULL imgURI"); + if (isIsolated) + *isIsolated = false; + + nsAutoCString spec; + if (imgURI) + imgURI->GetSpec(spec); + + nsAutoCString hostKey; + if (firstPartyIsolationURI && sThirdPartyUtilSvc) + sThirdPartyUtilSvc->GetFirstPartyHostForIsolation(firstPartyIsolationURI, hostKey); + + if (hostKey.Length() > 0) { + if (isIsolated) + *isIsolated = true; + // Make a new key using host + // FIXME: This might involve a couple more copies than necessary.. + // But man, 18 string types? Who knows which one I need to use to do + // this cheaply.. + return hostKey + nsAutoCString("&") + spec; + } else { + // No hostKey found, so don't isolate image to a first party. + return spec; + } +} + +nsAutoCString imgLoader::GetCacheKey(nsIURI *firstPartyIsolationURI, nsIURI* uri, + bool *isIsolated) { + nsRefPtr imageURI = new ImageURL(uri); + return GetCacheKey(firstPartyIsolationURI, imageURI, isIsolated); +} + /* imgIRequest loadImageWithChannelXPCOM(in nsIChannel channel, in imgINotificationObserver aObserver, in nsISupports cx, out nsIStreamListener); */ NS_IMETHODIMP imgLoader::LoadImageWithChannelXPCOM(nsIChannel *channel, imgINotificationObserver *aObserver, nsISupports *aCX, nsIStreamListener **listener, imgIRequest **_retval) { @@ -1855,29 +1906,35 @@ nsresult imgLoader::LoadImageWithChannel(nsIChannel *channel, imgINotificationOb MOZ_ASSERT(NS_UsePrivateBrowsing(channel) == mRespectPrivacy); + if (!sThirdPartyUtilSvc) + return NS_ERROR_FAILURE; + nsRefPtr request; nsCOMPtr uri; channel->GetURI(getter_AddRefs(uri)); + nsCOMPtr firstPartyIsolationURI; + sThirdPartyUtilSvc->GetFirstPartyIsolationURI(channel, nullptr, + getter_AddRefs(firstPartyIsolationURI)); + nsLoadFlags requestFlags = nsIRequest::LOAD_NORMAL; channel->GetLoadFlags(&requestFlags); nsRefPtr entry; + imgCacheTable &cache = GetCache(uri); + nsAutoCString key = GetCacheKey(firstPartyIsolationURI, uri, nullptr); if (requestFlags & nsIRequest::LOAD_BYPASS_CACHE) { - RemoveFromCache(uri); + imgCacheQueue &queue = GetCacheQueue(uri); + RemoveFromCache(key, cache, queue); } else { // Look in the cache for our URI, and then validate it. // 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. - imgCacheTable &cache = GetCache(uri); - nsAutoCString spec; - - uri->GetSpec(spec); - if (cache.Get(spec, getter_AddRefs(entry)) && entry) { + if (cache.Get(key, getter_AddRefs(entry)) && entry) { // We don't want to kick off another network load. So we ask // ValidateEntry to only do validation without creating a new proxy. If // it says that the entry isn't valid any more, we'll only use the entry @@ -1908,7 +1965,7 @@ nsresult imgLoader::LoadImageWithChannel(nsIChannel *channel, imgINotificationOb if (request && entry) { // If this entry has no proxies, its request has no reference to the entry. if (entry->HasNoProxies()) { - LOG_FUNC_WITH_PARAM(GetImgLog(), "imgLoader::LoadImageWithChannel() adding proxyless entry", "uri", spec.get()); + LOG_FUNC_WITH_PARAM(GetImgLog(), "imgLoader::LoadImageWithChannel() adding proxyless entry", "uri", key.get()); NS_ABORT_IF_FALSE(!request->HasCacheEntry(), "Proxyless entry's request has cache entry!"); request->SetCacheEntry(entry); @@ -1947,7 +2004,7 @@ nsresult imgLoader::LoadImageWithChannel(nsIChannel *channel, imgINotificationOb channel->GetOriginalURI(getter_AddRefs(originalURI)); // No principal specified here, because we're not passed one. - request->Init(originalURI, uri, channel, channel, entry, + request->Init(originalURI, uri, firstPartyIsolationURI, channel, channel, entry, aCX, nullptr, imgIRequest::CORS_NONE); ProxyListener *pl = new ProxyListener(static_cast(request.get())); @@ -1958,8 +2015,10 @@ nsresult imgLoader::LoadImageWithChannel(nsIChannel *channel, imgINotificationOb NS_RELEASE(pl); - // Try to add the new request into the cache. - PutIntoCache(originalURI, entry); + bool isIsolated = false; + nsAutoCString cacheKey = GetCacheKey(firstPartyIsolationURI, originalURI, &isIsolated); + if (isIsolated) // Try to add the new request into the cache. + PutIntoCache(cacheKey, entry); rv = CreateNewProxyForRequest(request, loadGroup, aObserver, requestFlags, _retval); @@ -2270,6 +2329,7 @@ NS_IMETHODIMP imgCacheValidator::OnStartRequest(nsIRequest *aRequest, nsISupport int32_t corsmode = mRequest->GetCORSMode(); nsCOMPtr loadingPrincipal = mRequest->GetLoadingPrincipal(); + nsCOMPtr firstPartyIsolationURI = mRequest->mFirstPartyIsolationURI; // Doom the old request's cache entry mRequest->RemoveFromCache(); @@ -2280,16 +2340,19 @@ NS_IMETHODIMP imgCacheValidator::OnStartRequest(nsIRequest *aRequest, nsISupport // We use originalURI here to fulfil the imgIRequest contract on GetURI. nsCOMPtr originalURI; channel->GetOriginalURI(getter_AddRefs(originalURI)); - mNewRequest->Init(originalURI, uri, aRequest, channel, mNewEntry, - mContext, loadingPrincipal, - corsmode); + mNewRequest->Init(originalURI, uri, firstPartyIsolationURI, aRequest, channel, + mNewEntry, mContext, loadingPrincipal, corsmode); mDestListener = new ProxyListener(mNewRequest); // Try to add the new request into the cache. Note that the entry must be in // the cache before the proxies' ownership changes, because adding a proxy // changes the caching behaviour for imgRequests. - mImgLoader->PutIntoCache(originalURI, mNewEntry); + bool isIsolated = false; + nsAutoCString key = mImgLoader->GetCacheKey(firstPartyIsolationURI, originalURI, + &isIsolated); + if (isIsolated) + mImgLoader->PutIntoCache(key, mNewEntry); uint32_t count = mProxies.Count(); for (int32_t i = count-1; i>=0; i--) {