LCOV - code coverage report
Current view: top level - image - ImageCacheKey.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 38 69 55.1 %
Date: 2017-07-14 16:53:18 Functions: 7 10 70.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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/Move.h"
       9             : #include "ImageURL.h"
      10             : #include "nsHostObjectProtocolHandler.h"
      11             : #include "nsString.h"
      12             : #include "mozilla/dom/File.h"
      13             : #include "mozilla/dom/workers/ServiceWorkerManager.h"
      14             : #include "nsIDocument.h"
      15             : #include "nsPrintfCString.h"
      16             : 
      17             : namespace mozilla {
      18             : 
      19             : using namespace dom;
      20             : 
      21             : namespace image {
      22             : 
      23             : bool
      24          90 : URISchemeIs(ImageURL* aURI, const char* aScheme)
      25             : {
      26          90 :   bool schemeMatches = false;
      27          90 :   if (NS_WARN_IF(NS_FAILED(aURI->SchemeIs(aScheme, &schemeMatches)))) {
      28           0 :     return false;
      29             :   }
      30          90 :   return schemeMatches;
      31             : }
      32             : 
      33             : static Maybe<uint64_t>
      34           0 : BlobSerial(ImageURL* aURI)
      35             : {
      36           0 :   nsAutoCString spec;
      37           0 :   aURI->GetSpec(spec);
      38             : 
      39           0 :   RefPtr<BlobImpl> blob;
      40           0 :   if (NS_SUCCEEDED(NS_GetBlobForBlobURISpec(spec, getter_AddRefs(blob))) &&
      41           0 :       blob) {
      42           0 :     return Some(blob->GetSerialNumber());
      43             :   }
      44             : 
      45           0 :   return Nothing();
      46             : }
      47             : 
      48          45 : ImageCacheKey::ImageCacheKey(nsIURI* aURI,
      49             :                              const OriginAttributes& aAttrs,
      50             :                              nsIDocument* aDocument,
      51          45 :                              nsresult& aRv)
      52          45 :   : mURI(new ImageURL(aURI, aRv))
      53             :   , mOriginAttributes(aAttrs)
      54          45 :   , mControlledDocument(GetControlledDocumentToken(aDocument))
      55          90 :   , mIsChrome(URISchemeIs(mURI, "chrome"))
      56             : {
      57          45 :   NS_ENSURE_SUCCESS_VOID(aRv);
      58             : 
      59          45 :   MOZ_ASSERT(NS_IsMainThread());
      60             : 
      61          45 :   if (URISchemeIs(mURI, "blob")) {
      62           0 :     mBlobSerial = BlobSerial(mURI);
      63             :   }
      64             : 
      65          45 :   mHash = ComputeHash(mURI, mBlobSerial, mOriginAttributes, mControlledDocument);
      66             : }
      67             : 
      68           0 : ImageCacheKey::ImageCacheKey(ImageURL* aURI,
      69             :                              const OriginAttributes& aAttrs,
      70           0 :                              nsIDocument* aDocument)
      71             :   : mURI(aURI)
      72             :   , mOriginAttributes(aAttrs)
      73           0 :   , mControlledDocument(GetControlledDocumentToken(aDocument))
      74           0 :   , mIsChrome(URISchemeIs(mURI, "chrome"))
      75             : {
      76           0 :   MOZ_ASSERT(aURI);
      77             : 
      78           0 :   if (URISchemeIs(mURI, "blob")) {
      79           0 :     mBlobSerial = BlobSerial(mURI);
      80             :   }
      81             : 
      82           0 :   mHash = ComputeHash(mURI, mBlobSerial, mOriginAttributes, mControlledDocument);
      83           0 : }
      84             : 
      85          82 : ImageCacheKey::ImageCacheKey(const ImageCacheKey& aOther)
      86             :   : mURI(aOther.mURI)
      87             :   , mBlobSerial(aOther.mBlobSerial)
      88             :   , mOriginAttributes(aOther.mOriginAttributes)
      89          82 :   , mControlledDocument(aOther.mControlledDocument)
      90          82 :   , mHash(aOther.mHash)
      91         246 :   , mIsChrome(aOther.mIsChrome)
      92          82 : { }
      93             : 
      94           0 : ImageCacheKey::ImageCacheKey(ImageCacheKey&& aOther)
      95           0 :   : mURI(Move(aOther.mURI))
      96           0 :   , mBlobSerial(Move(aOther.mBlobSerial))
      97             :   , mOriginAttributes(aOther.mOriginAttributes)
      98           0 :   , mControlledDocument(aOther.mControlledDocument)
      99           0 :   , mHash(aOther.mHash)
     100           0 :   , mIsChrome(aOther.mIsChrome)
     101           0 : { }
     102             : 
     103             : bool
     104          46 : ImageCacheKey::operator==(const ImageCacheKey& aOther) const
     105             : {
     106             :   // Don't share the image cache between a controlled document and anything else.
     107          46 :   if (mControlledDocument != aOther.mControlledDocument) {
     108           0 :     return false;
     109             :   }
     110             :   // The origin attributes always have to match.
     111          46 :   if (mOriginAttributes != aOther.mOriginAttributes) {
     112           0 :     return false;
     113             :   }
     114          46 :   if (mBlobSerial || aOther.mBlobSerial) {
     115             :     // If at least one of us has a blob serial, just compare the blob serial and
     116             :     // the ref portion of the URIs.
     117           0 :     return mBlobSerial == aOther.mBlobSerial &&
     118           0 :            mURI->HasSameRef(*aOther.mURI);
     119             :   }
     120             : 
     121             :   // For non-blob URIs, compare the URIs.
     122          46 :   return *mURI == *aOther.mURI;
     123             : }
     124             : 
     125             : const char*
     126          83 : ImageCacheKey::Spec() const
     127             : {
     128          83 :   return mURI->Spec();
     129             : }
     130             : 
     131             : /* static */ PLDHashNumber
     132          45 : ImageCacheKey::ComputeHash(ImageURL* aURI,
     133             :                            const Maybe<uint64_t>& aBlobSerial,
     134             :                            const OriginAttributes& aAttrs,
     135             :                            void* aControlledDocument)
     136             : {
     137             :   // Since we frequently call Hash() several times in a row on the same
     138             :   // ImageCacheKey, as an optimization we compute our hash once and store it.
     139             : 
     140          90 :   nsPrintfCString ptr("%p", aControlledDocument);
     141          90 :   nsAutoCString suffix;
     142          45 :   aAttrs.CreateSuffix(suffix);
     143             : 
     144          45 :   return AddToHash(0, aURI->ComputeHash(aBlobSerial),
     145          90 :                    HashString(suffix), HashString(ptr));
     146             : }
     147             : 
     148             : /* static */ void*
     149          45 : ImageCacheKey::GetControlledDocumentToken(nsIDocument* aDocument)
     150             : {
     151             :   // For non-controlled documents, we just return null.  For controlled
     152             :   // documents, we cast the pointer into a void* to avoid dereferencing
     153             :   // it (since we only use it for comparisons), and return it.
     154          45 :   void* pointer = nullptr;
     155             :   using dom::workers::ServiceWorkerManager;
     156          90 :   RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
     157          45 :   if (aDocument && swm) {
     158          90 :     ErrorResult rv;
     159          45 :     if (swm->IsControlled(aDocument, rv)) {
     160           0 :       pointer = aDocument;
     161             :     }
     162             :   }
     163          90 :   return pointer;
     164             : }
     165             : 
     166             : } // namespace image
     167             : } // namespace mozilla

Generated by: LCOV version 1.13