tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ImageCacheKey.cpp (3936B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #include "ImageCacheKey.h"
      7 
      8 #include "mozilla/AntiTrackingUtils.h"
      9 #include "mozilla/HashFunctions.h"
     10 #include "mozilla/StorageAccess.h"
     11 #include "mozilla/StoragePrincipalHelper.h"
     12 #include "mozilla/dom/Document.h"
     13 #include "mozilla/dom/ServiceWorkerManager.h"
     14 #include "mozilla/StaticPrefs_privacy.h"
     15 #include "mozilla/StorageAccess.h"
     16 #include "nsContentUtils.h"
     17 #include "nsHashKeys.h"
     18 #include "nsLayoutUtils.h"
     19 
     20 namespace mozilla {
     21 
     22 using namespace dom;
     23 
     24 namespace image {
     25 
     26 static nsIPrincipal* GetLoaderPrincipal(Document* aDocument) {
     27  return aDocument ? aDocument->NodePrincipal()
     28                   : nsContentUtils::GetSystemPrincipal();
     29 }
     30 
     31 static nsIPrincipal* GetPartitionPrincipal(Document* aDocument) {
     32  return aDocument ? aDocument->PartitionedPrincipal()
     33                   : nsContentUtils::GetSystemPrincipal();
     34 }
     35 
     36 ImageCacheKey::ImageCacheKey(nsIURI* aURI, CORSMode aCORSMode,
     37                             Document* aDocument)
     38    : mURI(aURI),
     39      mControlledDocument(GetSpecialCaseDocumentToken(aDocument)),
     40      mLoaderPrincipal(GetLoaderPrincipal(aDocument)),
     41      mPartitionPrincipal(GetPartitionPrincipal(aDocument)),
     42      mCORSMode(aCORSMode),
     43      mAppType(GetAppType(aDocument)) {
     44  MOZ_ASSERT(mLoaderPrincipal);
     45  MOZ_ASSERT(mPartitionPrincipal);
     46 }
     47 
     48 ImageCacheKey::ImageCacheKey(const ImageCacheKey& aOther) = default;
     49 ImageCacheKey::ImageCacheKey(ImageCacheKey&& aOther) = default;
     50 
     51 bool ImageCacheKey::operator==(const ImageCacheKey& aOther) const {
     52  // Don't share the image cache between a controlled document and anything
     53  // else.
     54  if (mControlledDocument != aOther.mControlledDocument) {
     55    return false;
     56  }
     57 
     58  if (!mPartitionPrincipal->Equals(aOther.mPartitionPrincipal)) {
     59    return false;
     60  }
     61 
     62  if (mCORSMode != aOther.mCORSMode) {
     63    return false;
     64  }
     65  // Don't share the image cache between two different appTypes
     66  if (mAppType != aOther.mAppType) {
     67    return false;
     68  }
     69 
     70  // For non-blob URIs, compare the URIs.
     71  bool equals = false;
     72  nsresult rv = mURI->Equals(aOther.mURI, &equals);
     73  return NS_SUCCEEDED(rv) && equals;
     74 }
     75 
     76 void ImageCacheKey::EnsureHash() const {
     77  MOZ_ASSERT(mHash.isNothing());
     78 
     79  // NOTE(emilio): Not adding the partition principal to the hash, since it
     80  // can mutate (see bug 1955775).
     81  nsAutoCString spec;
     82  (void)mURI->GetSpec(spec);
     83  mHash.emplace(
     84      AddToHash(HashString(spec), mControlledDocument, mAppType, mCORSMode));
     85 }
     86 
     87 /* static */
     88 void* ImageCacheKey::GetSpecialCaseDocumentToken(Document* aDocument) {
     89  // Cookie-averse documents can never have storage granted to them.  Since they
     90  // may not have inner windows, they would require special handling below, so
     91  // just bail out early here.
     92  if (!aDocument || aDocument->IsCookieAverse()) {
     93    return nullptr;
     94  }
     95 
     96  // For controlled documents, we cast the pointer into a void* to avoid
     97  // dereferencing it (since we only use it for comparisons).
     98  RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
     99  if (swm && aDocument->GetController().isSome()) {
    100    return aDocument;
    101  }
    102 
    103  return nullptr;
    104 }
    105 
    106 /* static */
    107 nsIDocShell::AppType ImageCacheKey::GetAppType(Document* aDocument) {
    108  if (!aDocument) {
    109    return nsIDocShell::APP_TYPE_UNKNOWN;
    110  }
    111 
    112  nsCOMPtr<nsIDocShellTreeItem> dsti = aDocument->GetDocShell();
    113  if (!dsti) {
    114    return nsIDocShell::APP_TYPE_UNKNOWN;
    115  }
    116 
    117  nsCOMPtr<nsIDocShellTreeItem> root;
    118  dsti->GetInProcessRootTreeItem(getter_AddRefs(root));
    119  if (nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(root)) {
    120    return docShell->GetAppType();
    121  }
    122  return nsIDocShell::APP_TYPE_UNKNOWN;
    123 }
    124 
    125 }  // namespace image
    126 }  // namespace mozilla