commit f2be42f3984acb20c58c05cf5534396fef635161 Author: Mike Perry mikeperry-git@fscked.org Date: Fri Aug 3 22:14:23 2012 -0700
Remove crashy cache isolation patch for now :/.
It asserts during debug builds, and also may have issues with XUL dialogs? --- ...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/0021-Isolate-the-Image-Cache-per-url-bar-domain.patch b/src/current-patches/firefox/alpha/0021-Isolate-the-Image-Cache-per-url-bar-domain.patch deleted file mode 100644 index b21536c..0000000 --- a/src/current-patches/firefox/alpha/0021-Isolate-the-Image-Cache-per-url-bar-domain.patch +++ /dev/null @@ -1,910 +0,0 @@ -From 1b18f231fce26c0b6d3c2bb2c6e30e30c8e05a1e Mon Sep 17 00:00:00 2001 -From: Mike Perry mikeperry-git@torproject.org -Date: Mon, 30 Jul 2012 18:37:36 -0700 -Subject: [PATCH 21/21] 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 6a415e9..62333f3 100644 ---- a/content/base/src/ThirdPartyUtil.cpp -+++ b/content/base/src/ThirdPartyUtil.cpp -@@ -40,6 +40,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" -@@ -54,6 +57,7 @@ ThirdPartyUtil::Init() - - nsresult rv; - mTLDService = do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID, &rv); -+ mCookiePermissions = do_GetService(NS_COOKIEPERMISSION_CONTRACTID); - return rv; - } - -@@ -315,3 +319,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 58ddb15..ba70162 100644 ---- a/content/base/src/ThirdPartyUtil.h -+++ b/content/base/src/ThirdPartyUtil.h -@@ -46,6 +46,7 @@ - class nsIURI; - class nsIChannel; - class nsIDOMWindow; -+class nsICookiePermission; - - class ThirdPartyUtil : public mozIThirdPartyUtil - { -@@ -61,6 +62,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 5c85697..4368609 100644 ---- a/content/base/src/nsContentUtils.cpp -+++ b/content/base/src/nsContentUtils.cpp -@@ -179,6 +179,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" -@@ -2629,8 +2630,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; -@@ -2647,11 +2646,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 045482a..78f5fc4 100644 ---- a/embedding/browser/webBrowser/nsContextMenuInfo.cpp -+++ b/embedding/browser/webBrowser/nsContextMenuInfo.cpp -@@ -62,6 +62,7 @@ - #include "nsIChannelPolicy.h" - #include "nsIContentSecurityPolicy.h" - #include "nsIContentPolicy.h" -+#include "mozIThirdPartyUtil.h" - - //***************************************************************************** - // class nsContextMenuInfo -@@ -305,15 +306,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) { -@@ -340,8 +341,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 577ee7e..c15ddc9 100644 ---- a/extensions/cookie/nsCookiePermission.cpp -+++ b/extensions/cookie/nsCookiePermission.cpp -@@ -445,6 +445,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 611b939..db9320b 100644 ---- a/image/public/imgILoader.idl -+++ b/image/public/imgILoader.idl -@@ -71,7 +71,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 -@@ -90,7 +90,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 36c8e6a..dd16771 100644 ---- a/image/src/imgLoader.cpp -+++ b/image/src/imgLoader.cpp -@@ -92,6 +92,7 @@ - #include "nsIHttpChannelInternal.h" - #include "nsIContentSecurityPolicy.h" - #include "nsIChannelPolicy.h" -+#include "mozIThirdPartyUtil.h" - - #include "nsContentUtils.h" - -@@ -504,7 +505,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, -@@ -556,7 +557,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); - } - -@@ -999,34 +1000,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() -@@ -1054,20 +1082,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()); -@@ -1077,13 +1103,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)); - } - -- if (!cache.Put(spec, entry)) -+ if (!cache.Put(key, entry)) - return false; - - // We can be called to resurrect an evicted entry. -@@ -1099,7 +1125,6 @@ bool imgLoader::PutIntoCache(nsIURI *key, imgCacheEntry *entry) - addrv = gCacheTracker->AddObject(entry); - - if (NS_SUCCEEDED(addrv)) { -- imgCacheQueue &queue = GetCacheQueue(key); - queue.Push(entry); - } - } -@@ -1205,7 +1230,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, -@@ -1257,7 +1282,7 @@ bool imgLoader::ValidateRequestWithNewChannel(imgRequest *request, - rv = NewImageChannel(getter_AddRefs(newChannel), - &forcePrincipalCheck, - aURI, -- aInitialDocumentURI, -+ aFirstPartyURI, - aReferrerURI, - aLoadGroup, - mAcceptHeader, -@@ -1326,7 +1351,7 @@ bool imgLoader::ValidateRequestWithNewChannel(imgRequest *request, - - bool imgLoader::ValidateEntry(imgCacheEntry *aEntry, - nsIURI *aURI, -- nsIURI *aInitialDocumentURI, -+ nsIURI *aFirstPartyURI, - nsIURI *aReferrerURI, - nsILoadGroup *aLoadGroup, - imgIDecoderObserver *aObserver, -@@ -1432,7 +1457,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, -@@ -1442,16 +1467,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()); - -@@ -1485,12 +1526,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()); - -@@ -1513,18 +1555,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"); -@@ -1532,7 +1562,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])) -@@ -1565,11 +1595,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, -@@ -1588,8 +1617,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; -@@ -1641,7 +1670,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()); -@@ -1680,7 +1709,7 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI, - rv = NewImageChannel(getter_AddRefs(newChannel), - &forcePrincipalCheck, - aURI, -- aInitialDocumentURI, -+ aFirstPartyURI, - aReferrerURI, - aLoadGroup, - mAcceptHeader, -@@ -1702,8 +1731,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); -@@ -1751,7 +1780,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); -@@ -1811,6 +1840,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) - { -@@ -1821,22 +1865,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 -@@ -1908,7 +1957,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())); -@@ -1920,7 +1969,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); -@@ -2207,6 +2256,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(); -@@ -2217,16 +2267,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 c0ba1d4..22671b3 100644 ---- a/image/src/imgLoader.h -+++ b/image/src/imgLoader.h -@@ -261,10 +261,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|. -@@ -349,9 +350,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 85ec2fa..cc40e86 100644 ---- a/image/src/imgRequest.cpp -+++ b/image/src/imgRequest.cpp -@@ -137,6 +137,7 @@ imgRequest::~imgRequest() - - nsresult imgRequest::Init(nsIURI *aURI, - nsIURI *aCurrentURI, -+ nsIURI *aFirstPartyURI, - nsIRequest *aRequest, - nsIChannel *aChannel, - imgCacheEntry *aCacheEntry, -@@ -158,6 +159,7 @@ nsresult imgRequest::Init(nsIURI *aURI, - - mURI = aURI; - mCurrentURI = aCurrentURI; -+ mFirstPartyURI = aFirstPartyURI; - mRequest = aRequest; - mChannel = aChannel; - mTimedChannel = do_QueryInterface(mChannel); -@@ -351,8 +353,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 7b200df..6ae7ae7 100644 ---- a/image/src/imgRequest.h -+++ b/image/src/imgRequest.h -@@ -91,6 +91,7 @@ public: - - nsresult Init(nsIURI *aURI, - nsIURI *aCurrentURI, -+ nsIURI *aFirstPartyURI, - nsIRequest *aRequest, - nsIChannel *aChannel, - imgCacheEntry *aCacheEntry, -@@ -221,6 +222,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 807aa6c..7bb866b 100644 ---- a/layout/generic/nsImageFrame.cpp -+++ b/layout/generic/nsImageFrame.cpp -@@ -96,6 +96,7 @@ - #include "nsLayoutErrors.h" - #include "nsBidiUtils.h" - #include "nsBidiPresUtils.h" -+#include "mozIThirdPartyUtil.h" - - #include "gfxRect.h" - #include "ImageLayers.h" -@@ -1760,9 +1761,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 ad41985..fd2cb38 100644 ---- a/netwerk/base/public/mozIThirdPartyUtil.idl -+++ b/netwerk/base/public/mozIThirdPartyUtil.idl -@@ -40,6 +40,7 @@ - interface nsIURI; - interface nsIDOMWindow; - interface nsIChannel; -+interface nsIDocument; - - /** - * Utility functions for determining whether a given URI, channel, or window -@@ -173,6 +174,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 c7f765b..d81e2e6 100644 ---- a/netwerk/cookie/nsICookiePermission.idl -+++ b/netwerk/cookie/nsICookiePermission.idl -@@ -40,6 +40,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 250e4fb..614e70f 100644 ---- a/toolkit/system/gnome/nsAlertsIconListener.cpp -+++ b/toolkit/system/gnome/nsAlertsIconListener.cpp -@@ -271,7 +271,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 9505ea2..bc9b856 100644 ---- a/widget/cocoa/nsMenuItemIconX.mm -+++ b/widget/cocoa/nsMenuItemIconX.mm -@@ -63,6 +63,7 @@ - #include "gfxImageSurface.h" - #include "imgIContainer.h" - #include "nsCocoaUtils.h" -+#include "mozIThirdPartyUtil.h" - - static const PRUint32 kIconWidth = 16; - static const PRUint32 kIconHeight = 16; -@@ -338,9 +339,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 -