commit 38858fcd57af55756a22fff7a90823416cd7b9a8
Author: Mike Perry <mikeperry-git(a)fscked.org>
Date: Wed Aug 29 13:25:47 2012 -0700
Remove the image cache patch from this branch.
---
...solate-the-Image-Cache-per-url-bar-domain.patch | 910 --------------------
1 files changed, 0 insertions(+), 910 deletions(-)
diff --git a/src/current-patches/firefox/alpha/0020-Isolate-the-Image-Cache-per-url-bar-domain.patch b/src/current-patches/firefox/alpha/0020-Isolate-the-Image-Cache-per-url-bar-domain.patch
deleted file mode 100644
index 4399ee7..0000000
--- a/src/current-patches/firefox/alpha/0020-Isolate-the-Image-Cache-per-url-bar-domain.patch
+++ /dev/null
@@ -1,910 +0,0 @@
-From 56be32e279b20c1dbb9af6524c3e06a8b3771e94 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git(a)torproject.org>
-Date: Tue, 28 Aug 2012 18:35:33 -0700
-Subject: [PATCH 20/20] Isolate the Image Cache per url bar domain.
-
-Also adds a new API to mozIThirdPartyUtil to allow you to get the url bar URI
-for a channel or nsIDocument.
----
- content/base/src/ThirdPartyUtil.cpp | 52 +++++
- content/base/src/ThirdPartyUtil.h | 2 +
- content/base/src/nsContentUtils.cpp | 13 +-
- embedding/browser/webBrowser/nsContextMenuInfo.cpp | 29 ++-
- extensions/cookie/nsCookiePermission.cpp | 3 +
- image/public/imgILoader.idl | 4 +-
- image/src/imgLoader.cpp | 200 ++++++++++++--------
- image/src/imgLoader.h | 13 +-
- image/src/imgRequest.cpp | 9 +-
- image/src/imgRequest.h | 3 +
- layout/generic/nsImageFrame.cpp | 11 +-
- netwerk/base/public/mozIThirdPartyUtil.idl | 21 ++
- netwerk/cookie/nsICookiePermission.idl | 1 +
- toolkit/system/gnome/nsAlertsIconListener.cpp | 3 +-
- widget/cocoa/nsMenuItemIconX.mm | 9 +-
- 15 files changed, 272 insertions(+), 101 deletions(-)
-
-diff --git a/content/base/src/ThirdPartyUtil.cpp b/content/base/src/ThirdPartyUtil.cpp
-index 97a000e..87ffc8a 100644
---- a/content/base/src/ThirdPartyUtil.cpp
-+++ b/content/base/src/ThirdPartyUtil.cpp
-@@ -7,6 +7,9 @@
- #include "nsIServiceManager.h"
- #include "nsIHttpChannelInternal.h"
- #include "nsIDOMWindow.h"
-+#include "nsICookiePermission.h"
-+#include "nsIDOMDocument.h"
-+#include "nsIDocument.h"
- #include "nsILoadContext.h"
- #include "nsIPrincipal.h"
- #include "nsIScriptObjectPrincipal.h"
-@@ -21,6 +24,7 @@ ThirdPartyUtil::Init()
-
- nsresult rv;
- mTLDService = do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID, &rv);
-+ mCookiePermissions = do_GetService(NS_COOKIEPERMISSION_CONTRACTID);
- return rv;
- }
-
-@@ -282,3 +286,51 @@ ThirdPartyUtil::GetBaseDomain(nsIURI* aHostURI,
-
- return NS_OK;
- }
-+
-+NS_IMETHODIMP
-+ThirdPartyUtil::GetFirstPartyURI(nsIChannel *aChannel,
-+ nsIDocument *aDoc,
-+ nsIURI **aOutput)
-+{
-+ nsresult rv = NS_ERROR_NULL_POINTER;
-+
-+ if (!aChannel && aDoc) {
-+ aChannel = aDoc->GetChannel();
-+ }
-+
-+ // If aChannel is specified or available, use the official route
-+ // for sure
-+ if (aChannel) {
-+ rv = mCookiePermissions->GetOriginatingURI(aChannel, aOutput);
-+ }
-+
-+ // If the channel was missing, closed or broken, try the
-+ // window hierarchy directly.
-+ //
-+ // This might fail to work for first-party loads themselves, but
-+ // we don't need this codepath for that case.
-+ if (NS_FAILED(rv) && aDoc) {
-+ nsCOMPtr<nsIDOMWindow> top;
-+ nsCOMPtr<nsIDOMDocument> topDDoc;
-+
-+ aDoc->GetWindow()->GetTop(getter_AddRefs(top));
-+ top->GetDocument(getter_AddRefs(topDDoc));
-+
-+ nsCOMPtr<nsIDocument> topDoc(do_QueryInterface(topDDoc));
-+ *aOutput = topDoc->GetOriginalURI();
-+
-+ if (*aOutput)
-+ rv = NS_OK;
-+ }
-+
-+ // TODO: We could provide a route through the loadgroup + notification
-+ // callbacks too, but either channel or document was always available
-+ // in the cases where this function was originally needed (the image cache).
-+ // The notification callbacks also appear to suffers from the same limitation
-+ // as the document path. See nsICookiePermissions.GetOriginatingURI() for
-+ // details.
-+
-+ return rv;
-+}
-+
-+
-diff --git a/content/base/src/ThirdPartyUtil.h b/content/base/src/ThirdPartyUtil.h
-index 269069b..37c30e8 100644
---- a/content/base/src/ThirdPartyUtil.h
-+++ b/content/base/src/ThirdPartyUtil.h
-@@ -9,6 +9,7 @@
- #include "nsString.h"
- #include "mozIThirdPartyUtil.h"
- #include "nsIEffectiveTLDService.h"
-+#include "nsICookiePermission.h"
-
- class nsIURI;
- class nsIChannel;
-@@ -28,6 +29,7 @@ private:
- static already_AddRefed<nsIURI> GetURIFromWindow(nsIDOMWindow* aWin);
-
- nsCOMPtr<nsIEffectiveTLDService> mTLDService;
-+ nsCOMPtr<nsICookiePermission> mCookiePermissions;
- };
-
- #endif
-diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp
-index 73cb024..951ba80 100644
---- a/content/base/src/nsContentUtils.cpp
-+++ b/content/base/src/nsContentUtils.cpp
-@@ -143,6 +143,7 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
- #include "nsIDOMHTMLInputElement.h"
- #include "nsParserConstants.h"
- #include "nsIWebNavigation.h"
-+#include "mozIThirdPartyUtil.h"
-
- #ifdef IBMBIDI
- #include "nsIBidiKeyboard.h"
-@@ -2647,8 +2648,6 @@ nsContentUtils::LoadImage(nsIURI* aURI, nsIDocument* aLoadingDocument,
- nsCOMPtr<nsILoadGroup> loadGroup = aLoadingDocument->GetDocumentLoadGroup();
- NS_ASSERTION(loadGroup, "Could not get loadgroup; onload may fire too early");
-
-- nsIURI *documentURI = aLoadingDocument->GetDocumentURI();
--
- // check for a Content Security Policy to pass down to the channel that
- // will get created to load the image
- nsCOMPtr<nsIChannelPolicy> channelPolicy;
-@@ -2665,11 +2664,15 @@ nsContentUtils::LoadImage(nsIURI* aURI, nsIDocument* aLoadingDocument,
-
- // Make the URI immutable so people won't change it under us
- NS_TryToSetImmutable(aURI);
-+
-+ nsCOMPtr<nsIURI> firstPartyURI;
-+ nsCOMPtr<mozIThirdPartyUtil> thirdPartySvc
-+ = do_GetService(THIRDPARTYUTIL_CONTRACTID);
-+ thirdPartySvc->GetFirstPartyURI(nsnull, aLoadingDocument,
-+ getter_AddRefs(firstPartyURI));
-
-- // XXXbz using "documentURI" for the initialDocumentURI is not quite
-- // right, but the best we can do here...
- return imgLoader->LoadImage(aURI, /* uri to load */
-- documentURI, /* initialDocumentURI */
-+ firstPartyURI, /* firstPartyURI */
- aReferrer, /* referrer */
- aLoadingPrincipal, /* loading principal */
- loadGroup, /* loadgroup */
-diff --git a/embedding/browser/webBrowser/nsContextMenuInfo.cpp b/embedding/browser/webBrowser/nsContextMenuInfo.cpp
-index 4db0d9f..8b57b55 100644
---- a/embedding/browser/webBrowser/nsContextMenuInfo.cpp
-+++ b/embedding/browser/webBrowser/nsContextMenuInfo.cpp
-@@ -26,6 +26,7 @@
- #include "nsIChannelPolicy.h"
- #include "nsIContentSecurityPolicy.h"
- #include "nsIContentPolicy.h"
-+#include "mozIThirdPartyUtil.h"
-
- //*****************************************************************************
- // class nsContextMenuInfo
-@@ -269,15 +270,15 @@ nsContextMenuInfo::GetBackgroundImageRequestInternal(nsIDOMNode *aDOMNode, imgIR
- nsCOMPtr<nsIPrincipal> principal;
- nsCOMPtr<nsIChannelPolicy> channelPolicy;
- nsCOMPtr<nsIContentSecurityPolicy> csp;
-- if (doc) {
-- principal = doc->NodePrincipal();
-- nsresult rv = principal->GetCsp(getter_AddRefs(csp));
-- NS_ENSURE_SUCCESS(rv, rv);
-- if (csp) {
-- channelPolicy = do_CreateInstance("@mozilla.org/nschannelpolicy;1");
-- channelPolicy->SetContentSecurityPolicy(csp);
-- channelPolicy->SetLoadType(nsIContentPolicy::TYPE_IMAGE);
-- }
-+ NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
-+
-+ principal = doc->NodePrincipal();
-+ nsresult rv = principal->GetCsp(getter_AddRefs(csp));
-+ NS_ENSURE_SUCCESS(rv, rv);
-+ if (csp) {
-+ channelPolicy = do_CreateInstance("@mozilla.org/nschannelpolicy;1");
-+ channelPolicy->SetContentSecurityPolicy(csp);
-+ channelPolicy->SetLoadType(nsIContentPolicy::TYPE_IMAGE);
- }
-
- while (true) {
-@@ -304,8 +305,14 @@ nsContextMenuInfo::GetBackgroundImageRequestInternal(nsIDOMNode *aDOMNode, imgIR
- nsCOMPtr<imgILoader> il(do_GetService(
- "@mozilla.org/image/loader;1"));
- NS_ENSURE_TRUE(il, NS_ERROR_FAILURE);
--
-- return il->LoadImage(bgUri, nsnull, nsnull, principal, nsnull,
-+
-+ nsCOMPtr<nsIURI> firstPartyURI;
-+ nsCOMPtr<mozIThirdPartyUtil> thirdPartySvc
-+ = do_GetService(THIRDPARTYUTIL_CONTRACTID);
-+ thirdPartySvc->GetFirstPartyURI(nsnull, doc,
-+ getter_AddRefs(firstPartyURI));
-+
-+ return il->LoadImage(bgUri, firstPartyURI, nsnull, principal, nsnull,
- nsnull, nsnull, nsIRequest::LOAD_NORMAL, nsnull,
- nsnull, channelPolicy, aRequest);
- }
-diff --git a/extensions/cookie/nsCookiePermission.cpp b/extensions/cookie/nsCookiePermission.cpp
-index 4d3cdc5..cbc0240 100644
---- a/extensions/cookie/nsCookiePermission.cpp
-+++ b/extensions/cookie/nsCookiePermission.cpp
-@@ -408,6 +408,9 @@ nsCookiePermission::GetOriginatingURI(nsIChannel *aChannel,
-
- return NS_OK;
- }
-+
-+ // TODO: Why don't we just use this here:
-+ // httpChannelInternal->GetDocumentURI(aURI);
- }
-
- // find the associated window and its top window
-diff --git a/image/public/imgILoader.idl b/image/public/imgILoader.idl
-index da26463..ecff309 100644
---- a/image/public/imgILoader.idl
-+++ b/image/public/imgILoader.idl
-@@ -38,7 +38,7 @@ interface imgILoader : nsISupports
- /**
- * Start the load and decode of an image.
- * @param aURI the URI to load
-- * @param aInitialDocumentURI the URI that 'initiated' the load -- used for 3rd party cookie blocking
-+ * @param aFirstPartyURI the urlbar URI that 'initiated' the load -- used for 3rd party blocking
- * @param aReferrerURI the 'referring' URI
- * @param aLoadingPrincipal the principal of the loading document
- * @param aLoadGroup Loadgroup to put the image load into
-@@ -57,7 +57,7 @@ interface imgILoader : nsISupports
- * goes away.
- */
- imgIRequest loadImage(in nsIURI aURI,
-- in nsIURI aInitialDocumentURL,
-+ in nsIURI aFirstPartyURI,
- in nsIURI aReferrerURI,
- in nsIPrincipal aLoadingPrincipal,
- in nsILoadGroup aLoadGroup,
-diff --git a/image/src/imgLoader.cpp b/image/src/imgLoader.cpp
-index 6cf52dd..3b28acb 100644
---- a/image/src/imgLoader.cpp
-+++ b/image/src/imgLoader.cpp
-@@ -58,6 +58,7 @@
- #include "nsIHttpChannelInternal.h"
- #include "nsIContentSecurityPolicy.h"
- #include "nsIChannelPolicy.h"
-+#include "mozIThirdPartyUtil.h"
-
- #include "nsContentUtils.h"
-
-@@ -470,7 +471,7 @@ static nsresult NewImageChannel(nsIChannel **aResult,
- // aLoadingPrincipal and false otherwise.
- bool *aForcePrincipalCheckForCacheEntry,
- nsIURI *aURI,
-- nsIURI *aInitialDocumentURI,
-+ nsIURI *aFirstPartyURI,
- nsIURI *aReferringURI,
- nsILoadGroup *aLoadGroup,
- const nsCString& aAcceptHeader,
-@@ -522,7 +523,7 @@ static nsresult NewImageChannel(nsIChannel **aResult,
-
- nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal = do_QueryInterface(newHttpChannel);
- NS_ENSURE_TRUE(httpChannelInternal, NS_ERROR_UNEXPECTED);
-- httpChannelInternal->SetDocumentURI(aInitialDocumentURI);
-+ httpChannelInternal->SetDocumentURI(aFirstPartyURI);
- newHttpChannel->SetReferrer(aReferringURI);
- }
-
-@@ -963,34 +964,61 @@ 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<imgCacheEntry> &aData,
-+ void *data)
-+{
-+ nsTArray<nsRefPtr<imgCacheEntry> > *entries =
-+ reinterpret_cast<nsTArray<nsRefPtr<imgCacheEntry> > *>(data);
-+
-+ entries->AppendElement(aData);
-+
-+ return PL_DHASH_NEXT;
-+}
-+
- /* imgIRequest findEntry(in nsIURI uri); */
- NS_IMETHODIMP imgLoader::FindEntryProperties(nsIURI *uri, nsIProperties **_retval)
- {
- nsRefPtr<imgCacheEntry> entry;
-- nsCAutoString spec;
- imgCacheTable &cache = GetCache(uri);
--
-- uri->GetSpec(spec);
- *_retval = nsnull;
-
-- if (cache.Get(spec, getter_AddRefs(entry)) && entry) {
-- if (gCacheTracker && entry->HasNoProxies())
-- gCacheTracker->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<nsRefPtr<imgCacheEntry> > entries;
-+ cache.Enumerate(EnumAllEntries, &entries);
-+
-+ for (PRUint32 i = 0; i < entries.Length(); ++i) {
-+ bool isEqual = false;
-
-- nsRefPtr<imgRequest> request = getter_AddRefs(entry->GetRequest());
-+ nsRefPtr<imgRequest> request = getter_AddRefs(entries[i]->GetRequest());
- if (request) {
-- *_retval = request->Properties();
-- NS_ADDREF(*_retval);
-+ request->mURI->Equals(uri, &isEqual);
-+ if (isEqual) {
-+ if (gCacheTracker && entries[i]->HasNoProxies())
-+ gCacheTracker->MarkUsed(entries[i]);
-+
-+ *_retval = request->Properties();
-+ }
- }
- }
-
-- return NS_OK;
-+ if (*_retval)
-+ return NS_OK;
-+
-+ return NS_ERROR_NOT_AVAILABLE;
- }
-
- void imgLoader::Shutdown()
-@@ -1018,20 +1046,18 @@ void imgLoader::MinimizeCaches()
- EvictEntries(sChromeCacheQueue);
- }
-
--bool imgLoader::PutIntoCache(nsIURI *key, imgCacheEntry *entry)
-+bool imgLoader::PutIntoCache(nsCAutoString key,
-+ imgCacheEntry *entry)
- {
-- imgCacheTable &cache = GetCache(key);
--
-- nsCAutoString spec;
-- key->GetSpec(spec);
--
-- LOG_STATIC_FUNC_WITH_PARAM(gImgLog, "imgLoader::PutIntoCache", "uri", spec.get());
-+ LOG_STATIC_FUNC_WITH_PARAM(gImgLog, "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<imgCacheEntry> tmpCacheEntry;
-- if (cache.Get(spec, getter_AddRefs(tmpCacheEntry)) && tmpCacheEntry) {
-+ if (cache.Get(key, getter_AddRefs(tmpCacheEntry)) && tmpCacheEntry) {
- PR_LOG(gImgLog, PR_LOG_DEBUG,
- ("[this=%p] imgLoader::PutIntoCache -- Element already in the cache", nsnull));
- nsRefPtr<imgRequest> tmpRequest = getter_AddRefs(tmpCacheEntry->GetRequest());
-@@ -1041,13 +1067,13 @@ bool imgLoader::PutIntoCache(nsIURI *key, imgCacheEntry *entry)
- PR_LOG(gImgLog, PR_LOG_DEBUG,
- ("[this=%p] imgLoader::PutIntoCache -- Replacing cached element", nsnull));
-
-- RemoveFromCache(key);
-+ RemoveKeyFromCache(cache, queue, key);
- } else {
- PR_LOG(gImgLog, PR_LOG_DEBUG,
- ("[this=%p] imgLoader::PutIntoCache -- Element NOT already in the cache", nsnull));
- }
-
-- cache.Put(spec, entry);
-+ cache.Put(key, entry);
-
- // We can be called to resurrect an evicted entry.
- if (entry->Evicted())
-@@ -1062,7 +1088,6 @@ bool imgLoader::PutIntoCache(nsIURI *key, imgCacheEntry *entry)
- addrv = gCacheTracker->AddObject(entry);
-
- if (NS_SUCCEEDED(addrv)) {
-- imgCacheQueue &queue = GetCacheQueue(key);
- queue.Push(entry);
- }
- }
-@@ -1168,7 +1193,7 @@ void imgLoader::CheckCacheLimits(imgCacheTable &cache, imgCacheQueue &queue)
-
- bool imgLoader::ValidateRequestWithNewChannel(imgRequest *request,
- nsIURI *aURI,
-- nsIURI *aInitialDocumentURI,
-+ nsIURI *aFirstPartyURI,
- nsIURI *aReferrerURI,
- nsILoadGroup *aLoadGroup,
- imgIDecoderObserver *aObserver,
-@@ -1220,7 +1245,7 @@ bool imgLoader::ValidateRequestWithNewChannel(imgRequest *request,
- rv = NewImageChannel(getter_AddRefs(newChannel),
- &forcePrincipalCheck,
- aURI,
-- aInitialDocumentURI,
-+ aFirstPartyURI,
- aReferrerURI,
- aLoadGroup,
- mAcceptHeader,
-@@ -1289,7 +1314,7 @@ bool imgLoader::ValidateRequestWithNewChannel(imgRequest *request,
-
- bool imgLoader::ValidateEntry(imgCacheEntry *aEntry,
- nsIURI *aURI,
-- nsIURI *aInitialDocumentURI,
-+ nsIURI *aFirstPartyURI,
- nsIURI *aReferrerURI,
- nsILoadGroup *aLoadGroup,
- imgIDecoderObserver *aObserver,
-@@ -1395,7 +1420,7 @@ bool imgLoader::ValidateEntry(imgCacheEntry *aEntry,
- if (validateRequest && aCanMakeNewChannel) {
- LOG_SCOPE(gImgLog, "imgLoader::ValidateRequest |cache hit| must validate");
-
-- return ValidateRequestWithNewChannel(request, aURI, aInitialDocumentURI,
-+ return ValidateRequestWithNewChannel(request, aURI, aFirstPartyURI,
- aReferrerURI, aLoadGroup, aObserver,
- aCX, aLoadFlags, aExistingRequest,
- aProxyRequest, aPolicy,
-@@ -1405,16 +1430,32 @@ bool imgLoader::ValidateEntry(imgCacheEntry *aEntry,
- return !validateRequest;
- }
-
--
--bool imgLoader::RemoveFromCache(nsIURI *aKey)
-+bool imgLoader::RemoveMatchingUrlsFromCache(nsIURI *aKey)
- {
-- if (!aKey) return false;
--
-+ bool rv = true;
- imgCacheTable &cache = GetCache(aKey);
-- imgCacheQueue &queue = GetCacheQueue(aKey);
-
-- nsCAutoString spec;
-- aKey->GetSpec(spec);
-+ // We have to make a temporary, since RemoveFromCache removes the element
-+ // from the queue, invalidating iterators.
-+ nsTArray<nsRefPtr<imgCacheEntry> > entries;
-+ cache.Enumerate(EnumAllEntries, &entries);
-+
-+ for (PRUint32 i = 0; i < entries.Length(); ++i) {
-+ bool isEqual = false;
-+
-+ entries[i]->mRequest->mURI->Equals(aKey, &isEqual);
-+ if (isEqual && !RemoveFromCache(entries[i]))
-+ rv = false;
-+ }
-+
-+ return rv;
-+}
-+
-+bool imgLoader::RemoveKeyFromCache(imgCacheTable &cache,
-+ imgCacheQueue &queue,
-+ nsCAutoString spec)
-+{
-+ if (spec.IsEmpty()) return false;
-
- LOG_STATIC_FUNC_WITH_PARAM(gImgLog, "imgLoader::RemoveFromCache", "uri", spec.get());
-
-@@ -1448,12 +1489,13 @@ bool imgLoader::RemoveFromCache(imgCacheEntry *entry)
-
- nsRefPtr<imgRequest> request(getter_AddRefs(entry->GetRequest()));
- if (request) {
-- nsCOMPtr<nsIURI> key;
-- if (NS_SUCCEEDED(request->GetURI(getter_AddRefs(key))) && key) {
-- imgCacheTable &cache = GetCache(key);
-- imgCacheQueue &queue = GetCacheQueue(key);
-- nsCAutoString spec;
-- key->GetSpec(spec);
-+ nsCOMPtr<nsIURI> imgURI = request->mURI;
-+ nsCOMPtr<nsIURI> firstPartyURI = request->mFirstPartyURI;
-+
-+ if (imgURI && firstPartyURI) {
-+ imgCacheTable &cache = GetCache(imgURI);
-+ imgCacheQueue &queue = GetCacheQueue(imgURI);
-+ nsCAutoString spec = GetCacheKey(firstPartyURI, imgURI);
-
- LOG_STATIC_FUNC_WITH_PARAM(gImgLog, "imgLoader::RemoveFromCache", "entry's uri", spec.get());
-
-@@ -1476,18 +1518,6 @@ bool imgLoader::RemoveFromCache(imgCacheEntry *entry)
- return false;
- }
-
--static PLDHashOperator EnumEvictEntries(const nsACString&,
-- nsRefPtr<imgCacheEntry> &aData,
-- void *data)
--{
-- nsTArray<nsRefPtr<imgCacheEntry> > *entries =
-- reinterpret_cast<nsTArray<nsRefPtr<imgCacheEntry> > *>(data);
--
-- entries->AppendElement(aData);
--
-- return PL_DHASH_NEXT;
--}
--
- nsresult imgLoader::EvictEntries(imgCacheTable &aCacheToClear)
- {
- LOG_STATIC_FUNC(gImgLog, "imgLoader::EvictEntries table");
-@@ -1495,7 +1525,7 @@ nsresult imgLoader::EvictEntries(imgCacheTable &aCacheToClear)
- // We have to make a temporary, since RemoveFromCache removes the element
- // from the queue, invalidating iterators.
- nsTArray<nsRefPtr<imgCacheEntry> > entries;
-- aCacheToClear.Enumerate(EnumEvictEntries, &entries);
-+ aCacheToClear.Enumerate(EnumAllEntries, &entries);
-
- for (PRUint32 i = 0; i < entries.Length(); ++i)
- if (!RemoveFromCache(entries[i]))
-@@ -1528,11 +1558,10 @@ nsresult imgLoader::EvictEntries(imgCacheQueue &aQueueToClear)
- nsIRequest::VALIDATE_NEVER | \
- nsIRequest::VALIDATE_ONCE_PER_SESSION)
-
--
--/* imgIRequest loadImage (in nsIURI aURI, in nsIURI initialDocumentURI, in nsIPrincipal loadingPrincipal, in nsILoadGroup aLoadGroup, in imgIDecoderObserver aObserver, in nsISupports aCX, in nsLoadFlags aLoadFlags, in nsISupports cacheKey, in imgIRequest aRequest); */
-+/* 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); */
-
- NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI,
-- nsIURI *aInitialDocumentURI,
-+ nsIURI *aFirstPartyURI,
- nsIURI *aReferrerURI,
- nsIPrincipal* aLoadingPrincipal,
- nsILoadGroup *aLoadGroup,
-@@ -1551,8 +1580,8 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI,
- if (!aURI)
- return NS_ERROR_NULL_POINTER;
-
-- nsCAutoString spec;
-- aURI->GetSpec(spec);
-+ nsCAutoString spec = GetCacheKey(aFirstPartyURI, aURI);
-+
- LOG_SCOPE_WITH_PARAM(gImgLog, "imgLoader::LoadImage", "aURI", spec.get());
-
- *_retval = nsnull;
-@@ -1604,7 +1633,7 @@ NS_IMETHODIMP 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, aFirstPartyURI, aReferrerURI,
- aLoadGroup, aObserver, aCX, requestFlags, true,
- aRequest, _retval, aPolicy, aLoadingPrincipal, corsmode)) {
- request = getter_AddRefs(entry->GetRequest());
-@@ -1643,7 +1672,7 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI,
- rv = NewImageChannel(getter_AddRefs(newChannel),
- &forcePrincipalCheck,
- aURI,
-- aInitialDocumentURI,
-+ aFirstPartyURI,
- aReferrerURI,
- aLoadGroup,
- mAcceptHeader,
-@@ -1665,8 +1694,8 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI,
- do_CreateInstance(NS_LOADGROUP_CONTRACTID);
- newChannel->SetLoadGroup(loadGroup);
-
-- request->Init(aURI, aURI, loadGroup, newChannel, entry, aCX,
-- aLoadingPrincipal, corsmode);
-+ request->Init(aURI, aURI, aFirstPartyURI, loadGroup, newChannel, entry,
-+ aCX, aLoadingPrincipal, corsmode);
-
- // Pass the inner window ID of the loading document, if possible.
- nsCOMPtr<nsIDocument> doc = do_QueryInterface(aCX);
-@@ -1714,7 +1743,7 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI,
- }
-
- // Try to add the new request into the cache.
-- PutIntoCache(aURI, entry);
-+ PutIntoCache(spec, entry);
- } else {
- LOG_MSG_WITH_PARAM(gImgLog,
- "imgLoader::LoadImage |cache hit|", "request", request);
-@@ -1774,6 +1803,21 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI,
- return NS_OK;
- }
-
-+nsCAutoString imgLoader::GetCacheKey(nsIURI *firstPartyURI, nsIURI *imgURI)
-+{
-+ nsCAutoString spec, hostKey;
-+ imgURI->GetSpec(spec);
-+
-+ // FIXME: Should we use mozIThirdPartyUtil to get a domain from this?
-+ firstPartyURI->GetHost(hostKey);
-+
-+ // 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 + nsCAutoString("&") + spec;
-+}
-+
- /* imgIRequest loadImageWithChannel(in nsIChannel channel, in imgIDecoderObserver aObserver, in nsISupports cx, out nsIStreamListener); */
- NS_IMETHODIMP imgLoader::LoadImageWithChannel(nsIChannel *channel, imgIDecoderObserver *aObserver, nsISupports *aCX, nsIStreamListener **listener, imgIRequest **_retval)
- {
-@@ -1784,22 +1828,27 @@ NS_IMETHODIMP imgLoader::LoadImageWithChannel(nsIChannel *channel, imgIDecoderOb
- nsCOMPtr<nsIURI> uri;
- channel->GetURI(getter_AddRefs(uri));
-
-+ nsCOMPtr<nsIURI> firstPartyURI;
-+ nsCOMPtr<mozIThirdPartyUtil> thirdPartySvc
-+ = do_GetService(THIRDPARTYUTIL_CONTRACTID);
-+ thirdPartySvc->GetFirstPartyURI(channel, nsnull,
-+ getter_AddRefs(firstPartyURI));
-+
- nsLoadFlags requestFlags = nsIRequest::LOAD_NORMAL;
- channel->GetLoadFlags(&requestFlags);
-
- nsRefPtr<imgCacheEntry> entry;
-+ imgCacheTable &cache = GetCache(uri);
-+ nsCAutoString spec = GetCacheKey(firstPartyURI, uri);
-
- if (requestFlags & nsIRequest::LOAD_BYPASS_CACHE) {
-- RemoveFromCache(uri);
-+ imgCacheQueue &queue = GetCacheQueue(uri);
-+ RemoveKeyFromCache(cache, queue, spec);
- } 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);
-- nsCAutoString spec;
--
-- uri->GetSpec(spec);
-
- if (cache.Get(spec, getter_AddRefs(entry)) && entry) {
- // We don't want to kick off another network load. So we ask
-@@ -1871,7 +1920,7 @@ NS_IMETHODIMP imgLoader::LoadImageWithChannel(nsIChannel *channel, imgIDecoderOb
- 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, firstPartyURI, channel, channel, entry,
- aCX, nsnull, imgIRequest::CORS_NONE);
-
- ProxyListener *pl = new ProxyListener(static_cast<nsIStreamListener *>(request.get()));
-@@ -1883,7 +1932,7 @@ NS_IMETHODIMP imgLoader::LoadImageWithChannel(nsIChannel *channel, imgIDecoderOb
- NS_RELEASE(pl);
-
- // Try to add the new request into the cache.
-- PutIntoCache(originalURI, entry);
-+ PutIntoCache(GetCacheKey(originalURI, firstPartyURI), entry);
-
- rv = CreateNewProxyForRequest(request, loadGroup, aObserver,
- requestFlags, nsnull, _retval);
-@@ -2170,6 +2219,7 @@ NS_IMETHODIMP imgCacheValidator::OnStartRequest(nsIRequest *aRequest, nsISupport
-
- PRInt32 corsmode = mRequest->GetCORSMode();
- nsCOMPtr<nsIPrincipal> loadingPrincipal = mRequest->GetLoadingPrincipal();
-+ nsCOMPtr<nsIURI> firstPartyURI = mRequest->mFirstPartyURI;
-
- // Doom the old request's cache entry
- mRequest->RemoveFromCache();
-@@ -2180,16 +2230,16 @@ NS_IMETHODIMP imgCacheValidator::OnStartRequest(nsIRequest *aRequest, nsISupport
- // We use originalURI here to fulfil the imgIRequest contract on GetURI.
- nsCOMPtr<nsIURI> originalURI;
- channel->GetOriginalURI(getter_AddRefs(originalURI));
-- mNewRequest->Init(originalURI, uri, aRequest, channel, mNewEntry,
-- mContext, loadingPrincipal,
-- corsmode);
-+ mNewRequest->Init(originalURI, uri, firstPartyURI, 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.
-- sImgLoader.PutIntoCache(originalURI, mNewEntry);
-+ sImgLoader.PutIntoCache(imgLoader::GetCacheKey(firstPartyURI, originalURI),
-+ mNewEntry);
-
- PRUint32 count = mProxies.Count();
- for (PRInt32 i = count-1; i>=0; i--) {
-diff --git a/image/src/imgLoader.h b/image/src/imgLoader.h
-index 9911a85..0451ae7 100644
---- a/image/src/imgLoader.h
-+++ b/image/src/imgLoader.h
-@@ -227,10 +227,11 @@ public:
-
- static nsresult InitCache();
-
-- static bool RemoveFromCache(nsIURI *aKey);
-+ static nsCAutoString GetCacheKey(nsIURI *firstPartyURI,
-+ nsIURI *imgURI);
- static bool RemoveFromCache(imgCacheEntry *entry);
--
-- static bool PutIntoCache(nsIURI *key, imgCacheEntry *entry);
-+ static bool PutIntoCache(nsCAutoString key, imgCacheEntry *entry);
-+ static bool RemoveMatchingUrlsFromCache(nsIURI *aKey);
-
- // Returns true if we should prefer evicting cache entry |two| over cache
- // entry |one|.
-@@ -315,9 +316,15 @@ private: // methods
- static void CacheEntriesChanged(nsIURI *aURI, PRInt32 sizediff = 0);
- static void CheckCacheLimits(imgCacheTable &cache, imgCacheQueue &queue);
-
-+ static bool RemoveKeyFromCache(imgCacheTable &cache,
-+ imgCacheQueue &queue,
-+ nsCAutoString key);
-+
-+
- private: // data
- friend class imgCacheEntry;
- friend class imgMemoryReporter;
-+ friend class imgRequest;
-
- static imgCacheTable sCache;
- static imgCacheQueue sCacheQueue;
-diff --git a/image/src/imgRequest.cpp b/image/src/imgRequest.cpp
-index 81e108a..28ff837 100644
---- a/image/src/imgRequest.cpp
-+++ b/image/src/imgRequest.cpp
-@@ -103,6 +103,7 @@ imgRequest::~imgRequest()
-
- nsresult imgRequest::Init(nsIURI *aURI,
- nsIURI *aCurrentURI,
-+ nsIURI *aFirstPartyURI,
- nsIRequest *aRequest,
- nsIChannel *aChannel,
- imgCacheEntry *aCacheEntry,
-@@ -124,6 +125,7 @@ nsresult imgRequest::Init(nsIURI *aURI,
-
- mURI = aURI;
- mCurrentURI = aCurrentURI;
-+ mFirstPartyURI = aFirstPartyURI;
- mRequest = aRequest;
- mChannel = aChannel;
- mTimedChannel = do_QueryInterface(mChannel);
-@@ -317,8 +319,11 @@ void imgRequest::RemoveFromCache()
- // mCacheEntry is nulled out when we have no more observers.
- if (mCacheEntry)
- imgLoader::RemoveFromCache(mCacheEntry);
-- else
-- imgLoader::RemoveFromCache(mURI);
-+ else {
-+ imgLoader::RemoveKeyFromCache(imgLoader::GetCache(mURI),
-+ imgLoader::GetCacheQueue(mURI),
-+ imgLoader::GetCacheKey(mFirstPartyURI, mURI));
-+ }
- }
-
- mCacheEntry = nsnull;
-diff --git a/image/src/imgRequest.h b/image/src/imgRequest.h
-index 3c2d1bc..f4399b2 100644
---- a/image/src/imgRequest.h
-+++ b/image/src/imgRequest.h
-@@ -57,6 +57,7 @@ public:
-
- nsresult Init(nsIURI *aURI,
- nsIURI *aCurrentURI,
-+ nsIURI *aFirstPartyURI,
- nsIRequest *aRequest,
- nsIChannel *aChannel,
- imgCacheEntry *aCacheEntry,
-@@ -189,6 +190,8 @@ private:
- nsCOMPtr<nsIURI> mURI;
- // The URI of the resource we ended up loading after all redirects, etc.
- nsCOMPtr<nsIURI> mCurrentURI;
-+ // The first party that triggered the load -- for cookie + cache isolation
-+ nsCOMPtr<nsIURI> mFirstPartyURI;
- // The principal of the document which loaded this image. Used when validating for CORS.
- nsCOMPtr<nsIPrincipal> mLoadingPrincipal;
- // The principal of this image.
-diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp
-index d0ed1c4..7d1e8a0 100644
---- a/layout/generic/nsImageFrame.cpp
-+++ b/layout/generic/nsImageFrame.cpp
-@@ -63,6 +63,7 @@
- #include "nsLayoutErrors.h"
- #include "nsBidiUtils.h"
- #include "nsBidiPresUtils.h"
-+#include "mozIThirdPartyUtil.h"
-
- #include "gfxRect.h"
- #include "ImageLayers.h"
-@@ -1794,9 +1795,17 @@ nsImageFrame::LoadIcon(const nsAString& aSpec,
-
- // For icon loads, we don't need to merge with the loadgroup flags
- nsLoadFlags loadFlags = nsIRequest::LOAD_NORMAL;
-+
-+ nsCOMPtr<nsIURI> firstPartyURI;
-+ nsCOMPtr<mozIThirdPartyUtil> thirdPartySvc
-+ = do_GetService(THIRDPARTYUTIL_CONTRACTID);
-+ // XXX: Should we pass the loadgroup, too? Is document ever likely
-+ // to be unset?
-+ thirdPartySvc->GetFirstPartyURI(nsnull, aPresContext->Document(),
-+ getter_AddRefs(firstPartyURI));
-
- return il->LoadImage(realURI, /* icon URI */
-- nsnull, /* initial document URI; this is only
-+ firstPartyURI, /* initial document URI; this is only
- relevant for cookies, so does not
- apply to icons. */
- nsnull, /* referrer (not relevant for icons) */
-diff --git a/netwerk/base/public/mozIThirdPartyUtil.idl b/netwerk/base/public/mozIThirdPartyUtil.idl
-index 578d8db..1869d14 100644
---- a/netwerk/base/public/mozIThirdPartyUtil.idl
-+++ b/netwerk/base/public/mozIThirdPartyUtil.idl
-@@ -7,6 +7,7 @@
- interface nsIURI;
- interface nsIDOMWindow;
- interface nsIChannel;
-+interface nsIDocument;
-
- /**
- * Utility functions for determining whether a given URI, channel, or window
-@@ -140,6 +141,26 @@ interface mozIThirdPartyUtil : nsISupports
- * @return the base domain.
- */
- AUTF8String getBaseDomain(in nsIURI aHostURI);
-+
-+
-+ /**
-+ * getFirstPartyURI
-+ *
-+ * Obtain the top-level url bar URI for either a channel or a document.
-+ * Either parameter may be null (but not both).
-+ *
-+ * @param aChannel
-+ * An arbitrary channel for some content element of a first party
-+ * load. Can be null.
-+ *
-+ * @param aDoc
-+ * An arbitrary third party document. Can be null.
-+ *
-+ * @return the first party url bar URI for the load.
-+ */
-+ nsIURI getFirstPartyURI(in nsIChannel aChannel,
-+ in nsIDocument aDoc);
-+
- };
-
- %{ C++
-diff --git a/netwerk/cookie/nsICookiePermission.idl b/netwerk/cookie/nsICookiePermission.idl
-index c576a46..5a753f3 100644
---- a/netwerk/cookie/nsICookiePermission.idl
-+++ b/netwerk/cookie/nsICookiePermission.idl
-@@ -7,6 +7,7 @@
- interface nsICookie2;
- interface nsIURI;
- interface nsIChannel;
-+interface nsIDocument;
-
- typedef long nsCookieAccess;
-
-diff --git a/toolkit/system/gnome/nsAlertsIconListener.cpp b/toolkit/system/gnome/nsAlertsIconListener.cpp
-index e6f4068..61927af 100644
---- a/toolkit/system/gnome/nsAlertsIconListener.cpp
-+++ b/toolkit/system/gnome/nsAlertsIconListener.cpp
-@@ -239,7 +239,8 @@ nsAlertsIconListener::StartRequest(const nsAString & aImageUrl)
- if (!il)
- return ShowAlert(NULL);
-
-- return il->LoadImage(imageUri, nsnull, nsnull, nsnull, nsnull, this,
-+ // XXX: Hrmm.... Bypass cache, or isolate to imageUrl?
-+ return il->LoadImage(imageUri, imageUri, nsnull, nsnull, nsnull, this,
- nsnull, nsIRequest::LOAD_NORMAL, nsnull, nsnull,
- nsnull, getter_AddRefs(mIconRequest));
- }
-diff --git a/widget/cocoa/nsMenuItemIconX.mm b/widget/cocoa/nsMenuItemIconX.mm
-index 9b40850..1a267d1 100644
---- a/widget/cocoa/nsMenuItemIconX.mm
-+++ b/widget/cocoa/nsMenuItemIconX.mm
-@@ -29,6 +29,7 @@
- #include "gfxImageSurface.h"
- #include "imgIContainer.h"
- #include "nsCocoaUtils.h"
-+#include "mozIThirdPartyUtil.h"
-
- static const PRUint32 kIconWidth = 16;
- static const PRUint32 kIconHeight = 16;
-@@ -304,9 +305,15 @@ nsMenuItemIconX::LoadIcon(nsIURI* aIconURI)
- [mNativeMenuItem setImage:sPlaceholderIconImage];
- }
-
-+ nsCOMPtr<nsIURI> firstPartyURI;
-+ nsCOMPtr<mozIThirdPartyUtil> thirdPartySvc
-+ = do_GetService(THIRDPARTYUTIL_CONTRACTID);
-+ thirdPartySvc->GetFirstPartyURI(nsnull, document,
-+ getter_AddRefs(firstPartyURI));
-+
- // Passing in null for channelPolicy here since nsMenuItemIconX::LoadIcon is
- // not exposed to web content
-- rv = loader->LoadImage(aIconURI, nsnull, nsnull, nsnull, loadGroup, this,
-+ rv = loader->LoadImage(aIconURI, firstPartyURI, nsnull, nsnull, loadGroup, this,
- nsnull, nsIRequest::LOAD_NORMAL, nsnull, nsnull,
- nsnull, getter_AddRefs(mIconRequest));
- if (NS_FAILED(rv)) return rv;
---
-1.7.5.4
-