commit e73d1f387758569e1b2d2031955ea53453c587c5 Author: Mike Perry mikeperry-git@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@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 -