From d3acf8a26173187cc526c0101127beec401dbfbb Mon Sep 17 00:00:00 2001 From: Nika Layzell Date: Mon, 28 Mar 2022 16:18:05 +0000 Subject: [PATCH] Bug 1728331 - Part 2: Respect AppType in ImageCacheKey, r=emilio This attribute is not used in Gecko, but exists for use by other applications. Specifically, the APP_TYPE_EDITOR type is given permission to load privileged images as tested by browser_docshell_type_editor.js. Before these changes, that test passed because the docshell was loaded in a different process, so the cache was empty when each load occurred, but after my changes the process ends up being re-used, so the image cache bypasses this check. This changes the image cache key to also include the app type information so that it will be compared before re-using the entry. Differential Revision: https://phabricator.services.mozilla.com/D126557 --- image/ImageCacheKey.cpp | 34 ++++++++++++++++++++++++++++++---- image/ImageCacheKey.h | 6 ++++++ 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/image/ImageCacheKey.cpp b/image/ImageCacheKey.cpp index 67819071bd36..11c4192f367c 100644 --- a/image/ImageCacheKey.cpp +++ b/image/ImageCacheKey.cpp @@ -35,7 +35,8 @@ ImageCacheKey::ImageCacheKey(nsIURI* aURI, const OriginAttributes& aAttrs, mOriginAttributes(aAttrs), mControlledDocument(GetSpecialCaseDocumentToken(aDocument)), mIsolationKey(GetIsolationKey(aDocument, aURI)), - mIsChrome(false) { + mIsChrome(false), + mAppType(GetAppType(aDocument)) { if (mURI->SchemeIs("chrome")) { mIsChrome = true; } @@ -47,7 +48,8 @@ ImageCacheKey::ImageCacheKey(const ImageCacheKey& aOther) mControlledDocument(aOther.mControlledDocument), mIsolationKey(aOther.mIsolationKey), mHash(aOther.mHash), - mIsChrome(aOther.mIsChrome) {} + mIsChrome(aOther.mIsChrome), + mAppType(aOther.mAppType) {} ImageCacheKey::ImageCacheKey(ImageCacheKey&& aOther) : mURI(std::move(aOther.mURI)), @@ -55,7 +57,8 @@ ImageCacheKey::ImageCacheKey(ImageCacheKey&& aOther) mControlledDocument(aOther.mControlledDocument), mIsolationKey(aOther.mIsolationKey), mHash(aOther.mHash), - mIsChrome(aOther.mIsChrome) {} + mIsChrome(aOther.mIsChrome), + mAppType(aOther.mAppType) {} bool ImageCacheKey::operator==(const ImageCacheKey& aOther) const { // Don't share the image cache between a controlled document and anything @@ -73,6 +76,10 @@ bool ImageCacheKey::operator==(const ImageCacheKey& aOther) const { if (mOriginAttributes != aOther.mOriginAttributes) { return false; } + // Don't share the image cache between two different appTypes + if (mAppType != aOther.mAppType) { + return false; + } // For non-blob URIs, compare the URIs. bool equals = false; @@ -96,7 +103,7 @@ void ImageCacheKey::EnsureHash() const { hash = HashString(spec); hash = AddToHash(hash, HashString(suffix), HashString(mIsolationKey), - HashString(ptr)); + HashString(ptr), mAppType); mHash.emplace(hash); } @@ -165,5 +172,24 @@ nsCString ImageCacheKey::GetIsolationKey(Document* aDocument, nsIURI* aURI) { return ""_ns; } +/* static */ +nsIDocShell::AppType ImageCacheKey::GetAppType(Document* aDocument) { + if (!aDocument) { + return nsIDocShell::APP_TYPE_UNKNOWN; + } + + nsCOMPtr dsti = aDocument->GetDocShell(); + if (!dsti) { + return nsIDocShell::APP_TYPE_UNKNOWN; + } + + nsCOMPtr root; + dsti->GetInProcessRootTreeItem(getter_AddRefs(root)); + if (nsCOMPtr docShell = do_QueryInterface(root)) { + return docShell->GetAppType(); + } + return nsIDocShell::APP_TYPE_UNKNOWN; +} + } // namespace image } // namespace mozilla diff --git a/image/ImageCacheKey.h b/image/ImageCacheKey.h index 7b728a1d1741..7c4fa286ea51 100644 --- a/image/ImageCacheKey.h +++ b/image/ImageCacheKey.h @@ -14,6 +14,7 @@ #include "mozilla/Maybe.h" #include "mozilla/RefPtr.h" #include "PLDHashTable.h" +#include "nsIDocShell.h" class nsIURI; @@ -70,6 +71,10 @@ class ImageCacheKey final { // document's base domain. This is handled by this method. static nsCString GetIsolationKey(dom::Document* aDocument, nsIURI* aURI); + // The AppType of the docshell an image is loaded in can influence whether the + // image is allowed to load. The specific AppType is fetched by this method. + static nsIDocShell::AppType GetAppType(dom::Document* aDocument); + void EnsureHash() const; nsCOMPtr mURI; @@ -78,6 +83,7 @@ class ImageCacheKey final { nsCString mIsolationKey; mutable Maybe mHash; bool mIsChrome; + nsIDocShell::AppType mAppType; }; } // namespace image