LCOV - code coverage report
Current view: top level - dom/file - nsHostObjectProtocolHandler.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 19 496 3.8 %
Date: 2017-07-14 16:53:18 Functions: 5 74 6.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "nsHostObjectProtocolHandler.h"
       8             : 
       9             : #include "DOMMediaStream.h"
      10             : #include "mozilla/dom/ContentChild.h"
      11             : #include "mozilla/dom/ContentParent.h"
      12             : #include "mozilla/dom/Exceptions.h"
      13             : #include "mozilla/dom/BlobImpl.h"
      14             : #include "mozilla/dom/IPCBlobUtils.h"
      15             : #include "mozilla/dom/MediaSource.h"
      16             : #include "mozilla/ipc/IPCStreamUtils.h"
      17             : #include "mozilla/LoadInfo.h"
      18             : #include "mozilla/ModuleUtils.h"
      19             : #include "mozilla/Preferences.h"
      20             : #include "mozilla/SystemGroup.h"
      21             : #include "nsClassHashtable.h"
      22             : #include "nsContentUtils.h"
      23             : #include "nsError.h"
      24             : #include "nsHostObjectURI.h"
      25             : #include "nsIMemoryReporter.h"
      26             : #include "nsIPrincipal.h"
      27             : #include "nsIUUIDGenerator.h"
      28             : #include "nsNetUtil.h"
      29             : 
      30             : #define RELEASING_TIMER 1000
      31             : 
      32             : using namespace mozilla;
      33             : using namespace mozilla::dom;
      34             : using namespace mozilla::ipc;
      35             : 
      36             : // -----------------------------------------------------------------------
      37             : // Hash table
      38           0 : struct DataInfo
      39             : {
      40             :   enum ObjectType {
      41             :     eBlobImpl,
      42             :     eMediaStream,
      43             :     eMediaSource
      44             :   };
      45             : 
      46           0 :   DataInfo(BlobImpl* aBlobImpl, nsIPrincipal* aPrincipal)
      47           0 :     : mObjectType(eBlobImpl)
      48             :     , mBlobImpl(aBlobImpl)
      49           0 :     , mPrincipal(aPrincipal)
      50           0 :   {}
      51             : 
      52           0 :   DataInfo(DOMMediaStream* aMediaStream, nsIPrincipal* aPrincipal)
      53           0 :     : mObjectType(eMediaStream)
      54             :     , mMediaStream(aMediaStream)
      55           0 :     , mPrincipal(aPrincipal)
      56           0 :   {}
      57             : 
      58           0 :   DataInfo(MediaSource* aMediaSource, nsIPrincipal* aPrincipal)
      59           0 :     : mObjectType(eMediaSource)
      60             :     , mMediaSource(aMediaSource)
      61           0 :     , mPrincipal(aPrincipal)
      62           0 :   {}
      63             : 
      64             :   ObjectType mObjectType;
      65             : 
      66             :   RefPtr<BlobImpl> mBlobImpl;
      67             :   RefPtr<DOMMediaStream> mMediaStream;
      68             :   RefPtr<MediaSource> mMediaSource;
      69             : 
      70             :   nsCOMPtr<nsIPrincipal> mPrincipal;
      71             :   nsCString mStack;
      72             : 
      73             :   // WeakReferences of nsHostObjectURI objects.
      74             :   nsTArray<nsWeakPtr> mURIs;
      75             : };
      76             : 
      77             : static nsClassHashtable<nsCStringHashKey, DataInfo>* gDataTable;
      78             : 
      79             : static DataInfo*
      80           1 : GetDataInfo(const nsACString& aUri)
      81             : {
      82           1 :   if (!gDataTable) {
      83           1 :     return nullptr;
      84             :   }
      85             : 
      86             :   DataInfo* res;
      87             : 
      88             :   // Let's remove any fragment and query from this URI.
      89           0 :   int32_t hasFragmentPos = aUri.FindChar('#');
      90           0 :   int32_t hasQueryPos = aUri.FindChar('?');
      91             : 
      92           0 :   int32_t pos = -1;
      93           0 :   if (hasFragmentPos >= 0 && hasQueryPos >= 0) {
      94           0 :     pos = std::min(hasFragmentPos, hasQueryPos);
      95           0 :   } else if (hasFragmentPos >= 0) {
      96           0 :     pos = hasFragmentPos;
      97             :   } else {
      98           0 :     pos = hasQueryPos;
      99             :   }
     100             : 
     101           0 :   if (pos < 0) {
     102           0 :     gDataTable->Get(aUri, &res);
     103             :   } else {
     104           0 :     gDataTable->Get(StringHead(aUri, pos), &res);
     105             :   }
     106             : 
     107           0 :   return res;
     108             : }
     109             : 
     110             : static DataInfo*
     111           1 : GetDataInfoFromURI(nsIURI* aURI)
     112             : {
     113           1 :   if (!aURI) {
     114           0 :     return nullptr;
     115             :   }
     116             : 
     117           2 :   nsCString spec;
     118           1 :   nsresult rv = aURI->GetSpec(spec);
     119           1 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     120           0 :     return nullptr;
     121             :   }
     122             : 
     123           1 :   return GetDataInfo(spec);
     124             : }
     125             : 
     126             : // Memory reporting for the hash table.
     127             : namespace mozilla {
     128             : 
     129             : void
     130           0 : BroadcastBlobURLRegistration(const nsACString& aURI,
     131             :                              BlobImpl* aBlobImpl,
     132             :                              nsIPrincipal* aPrincipal)
     133             : {
     134           0 :   MOZ_ASSERT(NS_IsMainThread());
     135           0 :   MOZ_ASSERT(aBlobImpl);
     136             : 
     137           0 :   if (XRE_IsParentProcess()) {
     138             :     dom::ContentParent::BroadcastBlobURLRegistration(aURI, aBlobImpl,
     139           0 :                                                      aPrincipal);
     140           0 :     return;
     141             :   }
     142             : 
     143           0 :   dom::ContentChild* cc = dom::ContentChild::GetSingleton();
     144             : 
     145           0 :   IPCBlob ipcBlob;
     146           0 :   nsresult rv = IPCBlobUtils::Serialize(aBlobImpl, cc, ipcBlob);
     147           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     148           0 :     return;
     149             :   }
     150             : 
     151           0 :   Unused << NS_WARN_IF(!cc->SendStoreAndBroadcastBlobURLRegistration(
     152             :     nsCString(aURI), ipcBlob, IPC::Principal(aPrincipal)));
     153             : }
     154             : 
     155             : void
     156           0 : BroadcastBlobURLUnregistration(const nsACString& aURI, DataInfo* aInfo)
     157             : {
     158           0 :   MOZ_ASSERT(aInfo);
     159           0 :   MOZ_ASSERT(NS_IsMainThread());
     160             : 
     161           0 :   if (XRE_IsParentProcess()) {
     162           0 :     dom::ContentParent::BroadcastBlobURLUnregistration(aURI);
     163           0 :     return;
     164             :   }
     165             : 
     166           0 :   dom::ContentChild* cc = dom::ContentChild::GetSingleton();
     167           0 :   Unused << NS_WARN_IF(!cc->SendUnstoreAndBroadcastBlobURLUnregistration(
     168             :     nsCString(aURI)));
     169             : }
     170             : 
     171           0 : class HostObjectURLsReporter final : public nsIMemoryReporter
     172             : {
     173           0 :   ~HostObjectURLsReporter() {}
     174             : 
     175             :  public:
     176             :   NS_DECL_ISUPPORTS
     177             : 
     178           0 :   NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
     179             :                             nsISupports* aData, bool aAnonymize) override
     180             :   {
     181           0 :     MOZ_COLLECT_REPORT(
     182             :       "host-object-urls", KIND_OTHER, UNITS_COUNT,
     183             :       gDataTable ? gDataTable->Count() : 0,
     184             :       "The number of host objects stored for access via URLs "
     185           0 :       "(e.g. blobs passed to URL.createObjectURL).");
     186             : 
     187           0 :     return NS_OK;
     188             :   }
     189             : };
     190             : 
     191           0 : NS_IMPL_ISUPPORTS(HostObjectURLsReporter, nsIMemoryReporter)
     192             : 
     193           0 : class BlobURLsReporter final : public nsIMemoryReporter
     194             : {
     195             :  public:
     196             :   NS_DECL_ISUPPORTS
     197             : 
     198           0 :   NS_IMETHOD CollectReports(nsIHandleReportCallback* aCallback,
     199             :                             nsISupports* aData, bool aAnonymize) override
     200             :   {
     201           0 :     if (!gDataTable) {
     202           0 :       return NS_OK;
     203             :     }
     204             : 
     205           0 :     nsDataHashtable<nsPtrHashKey<BlobImpl>, uint32_t> refCounts;
     206             : 
     207             :     // Determine number of URLs per BlobImpl, to handle the case where it's > 1.
     208           0 :     for (auto iter = gDataTable->Iter(); !iter.Done(); iter.Next()) {
     209           0 :       if (iter.UserData()->mObjectType != DataInfo::eBlobImpl) {
     210           0 :         continue;
     211             :       }
     212             : 
     213           0 :       BlobImpl* blobImpl = iter.UserData()->mBlobImpl;
     214           0 :       MOZ_ASSERT(blobImpl);
     215             : 
     216           0 :       refCounts.Put(blobImpl, refCounts.Get(blobImpl) + 1);
     217             :     }
     218             : 
     219           0 :     for (auto iter = gDataTable->Iter(); !iter.Done(); iter.Next()) {
     220           0 :       nsCStringHashKey::KeyType key = iter.Key();
     221           0 :       DataInfo* info = iter.UserData();
     222             : 
     223           0 :       if (iter.UserData()->mObjectType == DataInfo::eBlobImpl) {
     224           0 :         BlobImpl* blobImpl = iter.UserData()->mBlobImpl;
     225           0 :         MOZ_ASSERT(blobImpl);
     226             : 
     227           0 :         NS_NAMED_LITERAL_CSTRING(desc,
     228             :           "A blob URL allocated with URL.createObjectURL; the referenced "
     229             :           "blob cannot be freed until all URLs for it have been explicitly "
     230             :           "invalidated with URL.revokeObjectURL.");
     231           0 :         nsAutoCString path, url, owner, specialDesc;
     232           0 :         uint64_t size = 0;
     233           0 :         uint32_t refCount = 1;
     234           0 :         DebugOnly<bool> blobImplWasCounted;
     235             : 
     236           0 :         blobImplWasCounted = refCounts.Get(blobImpl, &refCount);
     237           0 :         MOZ_ASSERT(blobImplWasCounted);
     238           0 :         MOZ_ASSERT(refCount > 0);
     239             : 
     240           0 :         bool isMemoryFile = blobImpl->IsMemoryFile();
     241             : 
     242           0 :         if (isMemoryFile) {
     243           0 :           ErrorResult rv;
     244           0 :           size = blobImpl->GetSize(rv);
     245           0 :           if (NS_WARN_IF(rv.Failed())) {
     246           0 :             rv.SuppressException();
     247           0 :             size = 0;
     248             :           }
     249             :         }
     250             : 
     251           0 :         path = isMemoryFile ? "memory-blob-urls/" : "file-blob-urls/";
     252           0 :         BuildPath(path, key, info, aAnonymize);
     253             : 
     254           0 :         if (refCount > 1) {
     255           0 :           nsAutoCString addrStr;
     256             : 
     257           0 :           addrStr = "0x";
     258           0 :           addrStr.AppendInt((uint64_t)(BlobImpl*)blobImpl, 16);
     259             : 
     260           0 :           path += " ";
     261           0 :           path.AppendInt(refCount);
     262           0 :           path += "@";
     263           0 :           path += addrStr;
     264             : 
     265           0 :           specialDesc = desc;
     266           0 :           specialDesc += "\n\nNOTE: This blob (address ";
     267           0 :           specialDesc += addrStr;
     268           0 :           specialDesc += ") has ";
     269           0 :           specialDesc.AppendInt(refCount);
     270           0 :           specialDesc += " URLs.";
     271           0 :           if (isMemoryFile) {
     272           0 :             specialDesc += " Its size is divided ";
     273           0 :             specialDesc += refCount > 2 ? "among" : "between";
     274           0 :             specialDesc += " them in this report.";
     275             :           }
     276             :         }
     277             : 
     278           0 :         const nsACString& descString = specialDesc.IsEmpty()
     279           0 :             ? static_cast<const nsACString&>(desc)
     280           0 :             : static_cast<const nsACString&>(specialDesc);
     281           0 :         if (isMemoryFile) {
     282           0 :           aCallback->Callback(EmptyCString(),
     283             :               path,
     284             :               KIND_OTHER,
     285             :               UNITS_BYTES,
     286           0 :               size / refCount,
     287             :               descString,
     288           0 :               aData);
     289             :         } else {
     290           0 :           aCallback->Callback(EmptyCString(),
     291             :               path,
     292             :               KIND_OTHER,
     293             :               UNITS_COUNT,
     294             :               1,
     295             :               descString,
     296           0 :               aData);
     297             :         }
     298           0 :         continue;
     299             :       }
     300             : 
     301             :       // Just report the path for the DOMMediaStream or MediaSource.
     302           0 :       nsAutoCString path;
     303           0 :       path = iter.UserData()->mObjectType == DataInfo::eMediaSource
     304           0 :                ? "media-source-urls/" : "dom-media-stream-urls/";
     305           0 :       BuildPath(path, key, info, aAnonymize);
     306             : 
     307           0 :       NS_NAMED_LITERAL_CSTRING(desc,
     308             :         "An object URL allocated with URL.createObjectURL; the referenced "
     309             :         "data cannot be freed until all URLs for it have been explicitly "
     310             :         "invalidated with URL.revokeObjectURL.");
     311             : 
     312           0 :       aCallback->Callback(EmptyCString(), path, KIND_OTHER, UNITS_COUNT, 1,
     313           0 :                           desc, aData);
     314             :     }
     315             : 
     316           0 :     return NS_OK;
     317             :   }
     318             : 
     319             :   // Initialize info->mStack to record JS stack info, if enabled.
     320             :   // The string generated here is used in ReportCallback, below.
     321           0 :   static void GetJSStackForBlob(DataInfo* aInfo)
     322             :   {
     323           0 :     nsCString& stack = aInfo->mStack;
     324           0 :     MOZ_ASSERT(stack.IsEmpty());
     325           0 :     const uint32_t maxFrames = Preferences::GetUint("memory.blob_report.stack_frames");
     326             : 
     327           0 :     if (maxFrames == 0) {
     328           0 :       return;
     329             :     }
     330             : 
     331           0 :     nsCOMPtr<nsIStackFrame> frame = dom::GetCurrentJSStack(maxFrames);
     332             : 
     333           0 :     nsAutoCString origin;
     334           0 :     nsCOMPtr<nsIURI> principalURI;
     335           0 :     if (NS_SUCCEEDED(aInfo->mPrincipal->GetURI(getter_AddRefs(principalURI)))
     336           0 :         && principalURI) {
     337           0 :       principalURI->GetPrePath(origin);
     338             :     }
     339             : 
     340             :     // If we got a frame, we better have a current JSContext.  This is cheating
     341             :     // a bit; ideally we'd have our caller pass in a JSContext, or have
     342             :     // GetCurrentJSStack() hand out the JSContext it found.
     343           0 :     JSContext* cx = frame ? nsContentUtils::GetCurrentJSContext() : nullptr;
     344             : 
     345           0 :     for (uint32_t i = 0; frame; ++i) {
     346           0 :       nsString fileNameUTF16;
     347           0 :       int32_t lineNumber = 0;
     348             : 
     349           0 :       frame->GetFilename(cx, fileNameUTF16);
     350           0 :       frame->GetLineNumber(cx, &lineNumber);
     351             : 
     352           0 :       if (!fileNameUTF16.IsEmpty()) {
     353           0 :         NS_ConvertUTF16toUTF8 fileName(fileNameUTF16);
     354           0 :         stack += "js(";
     355           0 :         if (!origin.IsEmpty()) {
     356             :           // Make the file name root-relative for conciseness if possible.
     357             :           const char* originData;
     358             :           uint32_t originLen;
     359             : 
     360           0 :           originLen = origin.GetData(&originData);
     361             :           // If fileName starts with origin + "/", cut up to that "/".
     362           0 :           if (fileName.Length() >= originLen + 1 &&
     363           0 :               memcmp(fileName.get(), originData, originLen) == 0 &&
     364           0 :               fileName[originLen] == '/') {
     365           0 :             fileName.Cut(0, originLen);
     366             :           }
     367             :         }
     368           0 :         fileName.ReplaceChar('/', '\\');
     369           0 :         stack += fileName;
     370           0 :         if (lineNumber > 0) {
     371           0 :           stack += ", line=";
     372           0 :           stack.AppendInt(lineNumber);
     373             :         }
     374           0 :         stack += ")/";
     375             :       }
     376             : 
     377           0 :       nsCOMPtr<nsIStackFrame> caller;
     378           0 :       nsresult rv = frame->GetCaller(cx, getter_AddRefs(caller));
     379           0 :       NS_ENSURE_SUCCESS_VOID(rv);
     380           0 :       caller.swap(frame);
     381             :     }
     382             :   }
     383             : 
     384             :  private:
     385           0 :   ~BlobURLsReporter() {}
     386             : 
     387           0 :   static void BuildPath(nsAutoCString& path,
     388             :                         nsCStringHashKey::KeyType aKey,
     389             :                         DataInfo* aInfo,
     390             :                         bool anonymize)
     391             :   {
     392           0 :     nsCOMPtr<nsIURI> principalURI;
     393           0 :     nsAutoCString url, owner;
     394           0 :     if (NS_SUCCEEDED(aInfo->mPrincipal->GetURI(getter_AddRefs(principalURI))) &&
     395           0 :         principalURI != nullptr &&
     396           0 :         NS_SUCCEEDED(principalURI->GetSpec(owner)) &&
     397           0 :         !owner.IsEmpty()) {
     398           0 :       owner.ReplaceChar('/', '\\');
     399           0 :       path += "owner(";
     400           0 :       if (anonymize) {
     401           0 :         path += "<anonymized>";
     402             :       } else {
     403           0 :         path += owner;
     404             :       }
     405           0 :       path += ")";
     406             :     } else {
     407           0 :       path += "owner unknown";
     408             :     }
     409           0 :     path += "/";
     410           0 :     if (anonymize) {
     411           0 :       path += "<anonymized-stack>";
     412             :     } else {
     413           0 :       path += aInfo->mStack;
     414             :     }
     415           0 :     url = aKey;
     416           0 :     url.ReplaceChar('/', '\\');
     417           0 :     if (anonymize) {
     418           0 :       path += "<anonymized-url>";
     419             :     } else {
     420           0 :       path += url;
     421             :     }
     422           0 :   }
     423             : };
     424             : 
     425           0 : NS_IMPL_ISUPPORTS(BlobURLsReporter, nsIMemoryReporter)
     426             : 
     427             : class ReleasingTimerHolder final : public nsITimerCallback
     428             :                                  , public nsINamed
     429             : {
     430             : public:
     431             :   NS_DECL_ISUPPORTS
     432             : 
     433             :   static void
     434           0 :   Create(nsTArray<nsWeakPtr>&& aArray)
     435             :   {
     436           0 :     RefPtr<ReleasingTimerHolder> holder = new ReleasingTimerHolder(Move(aArray));
     437           0 :     holder->mTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
     438             : 
     439             :     // If we are shutting down, we are not able to create a timer.
     440           0 :     if (!holder->mTimer) {
     441           0 :       return;
     442             :     }
     443             : 
     444           0 :     MOZ_ALWAYS_SUCCEEDS(holder->mTimer->SetTarget(
     445             :       SystemGroup::EventTargetFor(TaskCategory::Other)));
     446             : 
     447           0 :     nsresult rv = holder->mTimer->InitWithCallback(holder, RELEASING_TIMER,
     448           0 :                                                    nsITimer::TYPE_ONE_SHOT);
     449           0 :     NS_ENSURE_SUCCESS_VOID(rv);
     450             :   }
     451             : 
     452             :   NS_IMETHOD
     453           0 :   Notify(nsITimer* aTimer) override
     454             :   {
     455           0 :     for (uint32_t i = 0; i < mURIs.Length(); ++i) {
     456           0 :       nsCOMPtr<nsIURI> uri = do_QueryReferent(mURIs[i]);
     457           0 :       if (uri) {
     458           0 :         static_cast<nsHostObjectURI*>(uri.get())->ForgetBlobImpl();
     459             :       }
     460             :     }
     461             : 
     462           0 :     return NS_OK;
     463             :   }
     464             : 
     465             :   NS_IMETHOD
     466           0 :   GetName(nsACString& aName) override
     467             :   {
     468           0 :     aName.AssignLiteral("ReleasingTimerHolder");
     469           0 :     return NS_OK;
     470             :   }
     471             : 
     472             :   NS_IMETHOD
     473           0 :   SetName(const char* aName) override
     474             :   {
     475           0 :     MOZ_CRASH("The name shall never be set!");
     476             :     return NS_OK;
     477             :   }
     478             : 
     479             : private:
     480           0 :   explicit ReleasingTimerHolder(nsTArray<nsWeakPtr>&& aArray)
     481           0 :     : mURIs(aArray)
     482           0 :   {}
     483             : 
     484           0 :   ~ReleasingTimerHolder()
     485           0 :   {}
     486             : 
     487             :   nsTArray<nsWeakPtr> mURIs;
     488             :   nsCOMPtr<nsITimer> mTimer;
     489             : };
     490             : 
     491           0 : NS_IMPL_ISUPPORTS(ReleasingTimerHolder, nsITimerCallback, nsINamed)
     492             : 
     493             : } // namespace mozilla
     494             : 
     495             : template<typename T>
     496             : static nsresult
     497           0 : AddDataEntryInternal(const nsACString& aURI, T aObject,
     498             :                      nsIPrincipal* aPrincipal)
     499             : {
     500           0 :   if (!gDataTable) {
     501           0 :     gDataTable = new nsClassHashtable<nsCStringHashKey, DataInfo>;
     502             :   }
     503             : 
     504           0 :   DataInfo* info = new DataInfo(aObject, aPrincipal);
     505           0 :   mozilla::BlobURLsReporter::GetJSStackForBlob(info);
     506             : 
     507           0 :   gDataTable->Put(aURI, info);
     508           0 :   return NS_OK;
     509             : }
     510             : 
     511             : void
     512           0 : nsHostObjectProtocolHandler::Init(void)
     513             : {
     514             :   static bool initialized = false;
     515             : 
     516           0 :   if (!initialized) {
     517           0 :     initialized = true;
     518           0 :     RegisterStrongMemoryReporter(new mozilla::HostObjectURLsReporter());
     519           0 :     RegisterStrongMemoryReporter(new mozilla::BlobURLsReporter());
     520             :   }
     521           0 : }
     522             : 
     523           0 : nsHostObjectProtocolHandler::nsHostObjectProtocolHandler()
     524             : {
     525           0 :   Init();
     526           0 : }
     527             : 
     528             : /* static */ nsresult
     529           0 : nsHostObjectProtocolHandler::AddDataEntry(BlobImpl* aBlobImpl,
     530             :                                           nsIPrincipal* aPrincipal,
     531             :                                           nsACString& aUri)
     532             : {
     533           0 :   Init();
     534             : 
     535           0 :   nsresult rv = GenerateURIStringForBlobURL(aPrincipal, aUri);
     536           0 :   NS_ENSURE_SUCCESS(rv, rv);
     537             : 
     538           0 :   rv = AddDataEntryInternal(aUri, aBlobImpl, aPrincipal);
     539           0 :   NS_ENSURE_SUCCESS(rv, rv);
     540             : 
     541           0 :   BroadcastBlobURLRegistration(aUri, aBlobImpl, aPrincipal);
     542           0 :   return NS_OK;
     543             : }
     544             : 
     545             : /* static */ nsresult
     546           0 : nsHostObjectProtocolHandler::AddDataEntry(DOMMediaStream* aMediaStream,
     547             :                                           nsIPrincipal* aPrincipal,
     548             :                                           nsACString& aUri)
     549             : {
     550           0 :   Init();
     551             : 
     552           0 :   nsresult rv = GenerateURIStringForBlobURL(aPrincipal, aUri);
     553           0 :   NS_ENSURE_SUCCESS(rv, rv);
     554             : 
     555           0 :   rv = AddDataEntryInternal(aUri, aMediaStream, aPrincipal);
     556           0 :   NS_ENSURE_SUCCESS(rv, rv);
     557             : 
     558           0 :   return NS_OK;
     559             : }
     560             : 
     561             : /* static */ nsresult
     562           0 : nsHostObjectProtocolHandler::AddDataEntry(MediaSource* aMediaSource,
     563             :                                           nsIPrincipal* aPrincipal,
     564             :                                           nsACString& aUri)
     565             : {
     566           0 :   Init();
     567             : 
     568           0 :   nsresult rv = GenerateURIStringForBlobURL(aPrincipal, aUri);
     569           0 :   NS_ENSURE_SUCCESS(rv, rv);
     570             : 
     571           0 :   rv = AddDataEntryInternal(aUri, aMediaSource, aPrincipal);
     572           0 :   NS_ENSURE_SUCCESS(rv, rv);
     573             : 
     574           0 :   return NS_OK;
     575             : }
     576             : 
     577             : /* static */ nsresult
     578           0 : nsHostObjectProtocolHandler::AddDataEntry(const nsACString& aURI,
     579             :                                           nsIPrincipal* aPrincipal,
     580             :                                           BlobImpl* aBlobImpl)
     581             : {
     582           0 :   return AddDataEntryInternal(aURI, aBlobImpl, aPrincipal);
     583             : }
     584             : 
     585             : /* static */ bool
     586           2 : nsHostObjectProtocolHandler::GetAllBlobURLEntries(
     587             :   nsTArray<BlobURLRegistrationData>& aRegistrations,
     588             :   ContentParent* aCP)
     589             : {
     590           2 :   MOZ_ASSERT(aCP);
     591             : 
     592           2 :   if (!gDataTable) {
     593           2 :     return true;
     594             :   }
     595             : 
     596           0 :   for (auto iter = gDataTable->ConstIter(); !iter.Done(); iter.Next()) {
     597           0 :     DataInfo* info = iter.UserData();
     598           0 :     MOZ_ASSERT(info);
     599             : 
     600           0 :     if (info->mObjectType != DataInfo::eBlobImpl) {
     601           0 :       continue;
     602             :     }
     603             : 
     604           0 :     MOZ_ASSERT(info->mBlobImpl);
     605             : 
     606           0 :     IPCBlob ipcBlob;
     607           0 :     nsresult rv = IPCBlobUtils::Serialize(info->mBlobImpl, aCP, ipcBlob);
     608           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     609           0 :       return false;
     610             :     }
     611             : 
     612           0 :     aRegistrations.AppendElement(BlobURLRegistrationData(
     613           0 :       nsCString(iter.Key()), ipcBlob, IPC::Principal(info->mPrincipal)));
     614             :   }
     615             : 
     616           0 :   return true;
     617             : }
     618             : 
     619             : /*static */ void
     620           0 : nsHostObjectProtocolHandler::RemoveDataEntry(const nsACString& aUri,
     621             :                                              bool aBroadcastToOtherProcesses)
     622             : {
     623           0 :   if (!gDataTable) {
     624           0 :     return;
     625             :   }
     626             : 
     627           0 :   DataInfo* info = GetDataInfo(aUri);
     628           0 :   if (!info) {
     629           0 :     return;
     630             :   }
     631             : 
     632           0 :   if (aBroadcastToOtherProcesses && info->mObjectType == DataInfo::eBlobImpl) {
     633           0 :     BroadcastBlobURLUnregistration(aUri, info);
     634             :   }
     635             : 
     636           0 :   if (!info->mURIs.IsEmpty()) {
     637           0 :     ReleasingTimerHolder::Create(Move(info->mURIs));
     638             :   }
     639             : 
     640           0 :   gDataTable->Remove(aUri);
     641           0 :   if (gDataTable->Count() == 0) {
     642           0 :     delete gDataTable;
     643           0 :     gDataTable = nullptr;
     644             :   }
     645             : }
     646             : 
     647             : /* static */ void
     648           0 : nsHostObjectProtocolHandler::RemoveDataEntries()
     649             : {
     650           0 :   MOZ_ASSERT(XRE_IsContentProcess());
     651             : 
     652           0 :   if (!gDataTable) {
     653           0 :     return;
     654             :   }
     655             : 
     656           0 :   gDataTable->Clear();
     657           0 :   delete gDataTable;
     658           0 :   gDataTable = nullptr;
     659             : }
     660             : 
     661             : /* static */ bool
     662           0 : nsHostObjectProtocolHandler::HasDataEntry(const nsACString& aUri)
     663             : {
     664           0 :   return !!GetDataInfo(aUri);
     665             : }
     666             : 
     667             : /* static */ nsresult
     668           0 : nsHostObjectProtocolHandler::GenerateURIString(const nsACString &aScheme,
     669             :                                                nsIPrincipal* aPrincipal,
     670             :                                                nsACString& aUri)
     671             : {
     672             :   nsresult rv;
     673             :   nsCOMPtr<nsIUUIDGenerator> uuidgen =
     674           0 :     do_GetService("@mozilla.org/uuid-generator;1", &rv);
     675           0 :   NS_ENSURE_SUCCESS(rv, rv);
     676             : 
     677             :   nsID id;
     678           0 :   rv = uuidgen->GenerateUUIDInPlace(&id);
     679           0 :   NS_ENSURE_SUCCESS(rv, rv);
     680             : 
     681             :   char chars[NSID_LENGTH];
     682           0 :   id.ToProvidedString(chars);
     683             : 
     684           0 :   aUri = aScheme;
     685           0 :   aUri.Append(':');
     686             : 
     687           0 :   if (aPrincipal) {
     688           0 :     nsAutoCString origin;
     689           0 :     rv = nsContentUtils::GetASCIIOrigin(aPrincipal, origin);
     690           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     691           0 :       return rv;
     692             :     }
     693             : 
     694           0 :     aUri.Append(origin);
     695           0 :     aUri.Append('/');
     696             :   }
     697             : 
     698           0 :   aUri += Substring(chars + 1, chars + NSID_LENGTH - 2);
     699             : 
     700           0 :   return NS_OK;
     701             : }
     702             : 
     703             : /* static */ nsresult
     704           0 : nsHostObjectProtocolHandler::GenerateURIStringForBlobURL(nsIPrincipal* aPrincipal,
     705             :                                                          nsACString& aUri)
     706             : {
     707             :   return
     708           0 :     GenerateURIString(NS_LITERAL_CSTRING(BLOBURI_SCHEME), aPrincipal, aUri);
     709             : }
     710             : 
     711             : /* static */ nsIPrincipal*
     712           0 : nsHostObjectProtocolHandler::GetDataEntryPrincipal(const nsACString& aUri)
     713             : {
     714           0 :   if (!gDataTable) {
     715           0 :     return nullptr;
     716             :   }
     717             : 
     718           0 :   DataInfo* res = GetDataInfo(aUri);
     719             : 
     720           0 :   if (!res) {
     721           0 :     return nullptr;
     722             :   }
     723             : 
     724           0 :   return res->mPrincipal;
     725             : }
     726             : 
     727             : /* static */ void
     728           0 : nsHostObjectProtocolHandler::Traverse(const nsACString& aUri,
     729             :                                       nsCycleCollectionTraversalCallback& aCallback)
     730             : {
     731           0 :   if (!gDataTable) {
     732           0 :     return;
     733             :   }
     734             : 
     735             :   DataInfo* res;
     736           0 :   gDataTable->Get(aUri, &res);
     737           0 :   if (!res) {
     738           0 :     return;
     739             :   }
     740             : 
     741           0 :   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCallback, "HostObjectProtocolHandler DataInfo.mBlobImpl");
     742           0 :   aCallback.NoteXPCOMChild(res->mBlobImpl);
     743             : 
     744           0 :   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCallback, "HostObjectProtocolHandler DataInfo.mMediaSource");
     745           0 :   aCallback.NoteXPCOMChild(res->mMediaSource);
     746             : 
     747           0 :   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCallback, "HostObjectProtocolHandler DataInfo.mMediaStream");
     748           0 :   aCallback.NoteXPCOMChild(res->mMediaStream);
     749             : }
     750             : 
     751             : // -----------------------------------------------------------------------
     752             : // Protocol handler
     753             : 
     754           0 : NS_IMPL_ISUPPORTS(nsHostObjectProtocolHandler, nsIProtocolHandler)
     755             : 
     756             : NS_IMETHODIMP
     757           0 : nsHostObjectProtocolHandler::GetDefaultPort(int32_t *result)
     758             : {
     759           0 :   *result = -1;
     760           0 :   return NS_OK;
     761             : }
     762             : 
     763             : NS_IMETHODIMP
     764           0 : nsHostObjectProtocolHandler::GetProtocolFlags(uint32_t *result)
     765             : {
     766           0 :   *result = URI_NORELATIVE | URI_NOAUTH | URI_LOADABLE_BY_SUBSUMERS |
     767             :             URI_NON_PERSISTABLE;
     768           0 :   return NS_OK;
     769             : }
     770             : 
     771             : NS_IMETHODIMP
     772           0 : nsHostObjectProtocolHandler::GetFlagsForURI(nsIURI *aURI, uint32_t *aResult)
     773             : {
     774           0 :   Unused << nsHostObjectProtocolHandler::GetProtocolFlags(aResult);
     775           0 :   if (IsFontTableURI(aURI) || IsBlobURI(aURI)) {
     776           0 :     *aResult |= URI_IS_LOCAL_RESOURCE;
     777             :   }
     778             : 
     779           0 :   return NS_OK;
     780             : }
     781             : 
     782             : NS_IMETHODIMP
     783           0 : nsBlobProtocolHandler::GetProtocolFlags(uint32_t *result)
     784             : {
     785           0 :   Unused << nsHostObjectProtocolHandler::GetProtocolFlags(result);
     786           0 :   *result |= URI_IS_LOCAL_RESOURCE;
     787           0 :   return NS_OK;
     788             : }
     789             : 
     790             : NS_IMETHODIMP
     791           0 : nsHostObjectProtocolHandler::NewURI(const nsACString& aSpec,
     792             :                                     const char *aCharset,
     793             :                                     nsIURI *aBaseURI,
     794             :                                     nsIURI **aResult)
     795             : {
     796           0 :   *aResult = nullptr;
     797             :   nsresult rv;
     798             : 
     799           0 :   DataInfo* info = GetDataInfo(aSpec);
     800             : 
     801           0 :   RefPtr<nsHostObjectURI> uri;
     802           0 :   if (info && info->mObjectType == DataInfo::eBlobImpl) {
     803           0 :     MOZ_ASSERT(info->mBlobImpl);
     804           0 :     uri = new nsHostObjectURI(info->mPrincipal, info->mBlobImpl);
     805             :   } else {
     806           0 :     uri = new nsHostObjectURI(nullptr, nullptr);
     807             :   }
     808             : 
     809           0 :   rv = uri->SetSpec(aSpec);
     810           0 :   NS_ENSURE_SUCCESS(rv, rv);
     811             : 
     812           0 :   NS_TryToSetImmutable(uri);
     813           0 :   uri.forget(aResult);
     814             : 
     815           0 :   if (info && info->mObjectType == DataInfo::eBlobImpl) {
     816           0 :     info->mURIs.AppendElement(do_GetWeakReference(*aResult));
     817             :   }
     818             : 
     819           0 :   return NS_OK;
     820             : }
     821             : 
     822             : NS_IMETHODIMP
     823           0 : nsHostObjectProtocolHandler::NewChannel2(nsIURI* uri,
     824             :                                          nsILoadInfo* aLoadInfo,
     825             :                                          nsIChannel** result)
     826             : {
     827           0 :   *result = nullptr;
     828             : 
     829           0 :   nsCOMPtr<nsIURIWithBlobImpl> uriBlobImpl = do_QueryInterface(uri);
     830           0 :   if (!uriBlobImpl) {
     831           0 :     return NS_ERROR_DOM_BAD_URI;
     832             :   }
     833             : 
     834           0 :   nsCOMPtr<nsISupports> tmp;
     835           0 :   MOZ_ALWAYS_SUCCEEDS(uriBlobImpl->GetBlobImpl(getter_AddRefs(tmp)));
     836           0 :   nsCOMPtr<BlobImpl> blobImpl = do_QueryInterface(tmp);
     837           0 :   if (!blobImpl) {
     838           0 :     return NS_ERROR_DOM_BAD_URI;
     839             :   }
     840             : 
     841             : #ifdef DEBUG
     842           0 :   DataInfo* info = GetDataInfoFromURI(uri);
     843             : 
     844             :   // Info can be null, in case this blob URL has been revoked already.
     845           0 :   if (info) {
     846           0 :     nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(uri);
     847           0 :     nsCOMPtr<nsIPrincipal> principal;
     848           0 :     uriPrinc->GetPrincipal(getter_AddRefs(principal));
     849           0 :     MOZ_ASSERT(info->mPrincipal == principal, "Wrong principal!");
     850             :   }
     851             : #endif
     852             : 
     853           0 :   ErrorResult rv;
     854           0 :   nsCOMPtr<nsIInputStream> stream;
     855           0 :   blobImpl->GetInternalStream(getter_AddRefs(stream), rv);
     856           0 :   if (NS_WARN_IF(rv.Failed())) {
     857           0 :     return rv.StealNSResult();
     858             :   }
     859             : 
     860           0 :   nsAutoString contentType;
     861           0 :   blobImpl->GetType(contentType);
     862             : 
     863           0 :   nsCOMPtr<nsIChannel> channel;
     864           0 :   rv = NS_NewInputStreamChannelInternal(getter_AddRefs(channel),
     865             :                                         uri,
     866             :                                         stream,
     867           0 :                                         NS_ConvertUTF16toUTF8(contentType),
     868           0 :                                         EmptyCString(), // aContentCharset
     869           0 :                                         aLoadInfo);
     870           0 :   if (NS_WARN_IF(rv.Failed())) {
     871           0 :     return rv.StealNSResult();
     872             :   }
     873             : 
     874           0 :   if (blobImpl->IsFile()) {
     875           0 :     nsString filename;
     876           0 :     blobImpl->GetName(filename);
     877           0 :     channel->SetContentDispositionFilename(filename);
     878             :   }
     879             : 
     880           0 :   uint64_t size = blobImpl->GetSize(rv);
     881           0 :   if (NS_WARN_IF(rv.Failed())) {
     882           0 :     return rv.StealNSResult();
     883             :   }
     884             : 
     885           0 :   channel->SetOriginalURI(uri);
     886           0 :   channel->SetContentType(NS_ConvertUTF16toUTF8(contentType));
     887           0 :   channel->SetContentLength(size);
     888             : 
     889           0 :   channel.forget(result);
     890             : 
     891           0 :   return NS_OK;
     892             : }
     893             : 
     894             : NS_IMETHODIMP
     895           0 : nsHostObjectProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
     896             : {
     897           0 :   return NewChannel2(uri, nullptr, result);
     898             : }
     899             : 
     900             : NS_IMETHODIMP
     901           0 : nsHostObjectProtocolHandler::AllowPort(int32_t port, const char *scheme,
     902             :                                        bool *_retval)
     903             : {
     904             :   // don't override anything.
     905           0 :   *_retval = false;
     906           0 :   return NS_OK;
     907             : }
     908             : 
     909             : NS_IMETHODIMP
     910           0 : nsBlobProtocolHandler::GetScheme(nsACString &result)
     911             : {
     912           0 :   result.AssignLiteral(BLOBURI_SCHEME);
     913           0 :   return NS_OK;
     914             : }
     915             : 
     916             : NS_IMETHODIMP
     917           0 : nsFontTableProtocolHandler::GetProtocolFlags(uint32_t *result)
     918             : {
     919           0 :   Unused << nsHostObjectProtocolHandler::GetProtocolFlags(result);
     920           0 :   *result |= URI_IS_LOCAL_RESOURCE;
     921           0 :   return NS_OK;
     922             : }
     923             : 
     924             : NS_IMETHODIMP
     925           0 : nsFontTableProtocolHandler::GetScheme(nsACString &result)
     926             : {
     927           0 :   result.AssignLiteral(FONTTABLEURI_SCHEME);
     928           0 :   return NS_OK;
     929             : }
     930             : 
     931             : nsresult
     932           0 : NS_GetBlobForBlobURI(nsIURI* aURI, BlobImpl** aBlob)
     933             : {
     934           0 :   *aBlob = nullptr;
     935             : 
     936           0 :   DataInfo* info = GetDataInfoFromURI(aURI);
     937           0 :   if (!info || info->mObjectType != DataInfo::eBlobImpl) {
     938           0 :     return NS_ERROR_DOM_BAD_URI;
     939             :   }
     940             : 
     941           0 :   RefPtr<BlobImpl> blob = info->mBlobImpl;
     942           0 :   blob.forget(aBlob);
     943           0 :   return NS_OK;
     944             : }
     945             : 
     946             : nsresult
     947           0 : NS_GetBlobForBlobURISpec(const nsACString& aSpec, BlobImpl** aBlob)
     948             : {
     949           0 :   *aBlob = nullptr;
     950             : 
     951           0 :   DataInfo* info = GetDataInfo(aSpec);
     952           0 :   if (!info || info->mObjectType != DataInfo::eBlobImpl) {
     953           0 :     return NS_ERROR_DOM_BAD_URI;
     954             :   }
     955             : 
     956           0 :   RefPtr<BlobImpl> blob = info->mBlobImpl;
     957           0 :   blob.forget(aBlob);
     958           0 :   return NS_OK;
     959             : }
     960             : 
     961             : nsresult
     962           0 : NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream)
     963             : {
     964           0 :   RefPtr<BlobImpl> blobImpl;
     965           0 :   ErrorResult rv;
     966           0 :   rv = NS_GetBlobForBlobURI(aURI, getter_AddRefs(blobImpl));
     967           0 :   if (NS_WARN_IF(rv.Failed())) {
     968           0 :     return rv.StealNSResult();
     969             :   }
     970             : 
     971           0 :   blobImpl->GetInternalStream(aStream, rv);
     972           0 :   if (NS_WARN_IF(rv.Failed())) {
     973           0 :     return rv.StealNSResult();
     974             :   }
     975             : 
     976           0 :   return NS_OK;
     977             : }
     978             : 
     979             : nsresult
     980           0 : NS_GetStreamForMediaStreamURI(nsIURI* aURI, DOMMediaStream** aStream)
     981             : {
     982           0 :   DataInfo* info = GetDataInfoFromURI(aURI);
     983           0 :   if (!info || info->mObjectType != DataInfo::eMediaStream) {
     984           0 :     return NS_ERROR_DOM_BAD_URI;
     985             :   }
     986             : 
     987           0 :   RefPtr<DOMMediaStream> mediaStream = info->mMediaStream;
     988           0 :   mediaStream.forget(aStream);
     989           0 :   return NS_OK;
     990             : }
     991             : 
     992             : NS_IMETHODIMP
     993           0 : nsFontTableProtocolHandler::NewURI(const nsACString& aSpec,
     994             :                                    const char *aCharset,
     995             :                                    nsIURI *aBaseURI,
     996             :                                    nsIURI **aResult)
     997             : {
     998           0 :   RefPtr<nsIURI> uri;
     999             : 
    1000             :   // Either you got here via a ref or a fonttable: uri
    1001           0 :   if (aSpec.Length() && aSpec.CharAt(0) == '#') {
    1002           0 :     nsresult rv = aBaseURI->CloneIgnoringRef(getter_AddRefs(uri));
    1003           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1004             : 
    1005           0 :     uri->SetRef(aSpec);
    1006             :   } else {
    1007             :     // Relative URIs (other than #ref) are not meaningful within the
    1008             :     // fonttable: scheme.
    1009             :     // If aSpec is a relative URI -other- than a bare #ref,
    1010             :     // this will leave uri empty, and we'll return a failure code below.
    1011           0 :     uri = new mozilla::net::nsSimpleURI();
    1012           0 :     nsresult rv = uri->SetSpec(aSpec);
    1013           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1014             :   }
    1015             : 
    1016             :   bool schemeIs;
    1017           0 :   if (NS_FAILED(uri->SchemeIs(FONTTABLEURI_SCHEME, &schemeIs)) || !schemeIs) {
    1018           0 :     NS_WARNING("Non-fonttable spec in nsFontTableProtocolHander");
    1019           0 :     return NS_ERROR_NOT_AVAILABLE;
    1020             :   }
    1021             : 
    1022           0 :   uri.forget(aResult);
    1023           0 :   return NS_OK;
    1024             : }
    1025             : 
    1026             : nsresult
    1027           0 : NS_GetSourceForMediaSourceURI(nsIURI* aURI, MediaSource** aSource)
    1028             : {
    1029           0 :   *aSource = nullptr;
    1030             : 
    1031           0 :   DataInfo* info = GetDataInfoFromURI(aURI);
    1032           0 :   if (!info || info->mObjectType != DataInfo::eMediaSource) {
    1033           0 :     return NS_ERROR_DOM_BAD_URI;
    1034             :   }
    1035             : 
    1036           0 :   RefPtr<MediaSource> mediaSource = info->mMediaSource;
    1037           0 :   mediaSource.forget(aSource);
    1038           0 :   return NS_OK;
    1039             : }
    1040             : 
    1041             : #define NS_BLOBPROTOCOLHANDLER_CID \
    1042             : { 0xb43964aa, 0xa078, 0x44b2, \
    1043             :   { 0xb0, 0x6b, 0xfd, 0x4d, 0x1b, 0x17, 0x2e, 0x66 } }
    1044             : 
    1045             : #define NS_FONTTABLEPROTOCOLHANDLER_CID \
    1046             : { 0x3fc8f04e, 0xd719, 0x43ca, \
    1047             :   { 0x9a, 0xd0, 0x18, 0xee, 0x32, 0x02, 0x11, 0xf2 } }
    1048             : 
    1049           0 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsBlobProtocolHandler)
    1050           0 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsFontTableProtocolHandler)
    1051             : 
    1052             : NS_DEFINE_NAMED_CID(NS_BLOBPROTOCOLHANDLER_CID);
    1053             : NS_DEFINE_NAMED_CID(NS_FONTTABLEPROTOCOLHANDLER_CID);
    1054             : 
    1055             : static const mozilla::Module::CIDEntry kHostObjectProtocolHandlerCIDs[] = {
    1056             :   { &kNS_BLOBPROTOCOLHANDLER_CID, false, nullptr, nsBlobProtocolHandlerConstructor },
    1057             :   { &kNS_FONTTABLEPROTOCOLHANDLER_CID, false, nullptr, nsFontTableProtocolHandlerConstructor },
    1058             :   { nullptr }
    1059             : };
    1060             : 
    1061             : static const mozilla::Module::ContractIDEntry kHostObjectProtocolHandlerContracts[] = {
    1062             :   { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX BLOBURI_SCHEME, &kNS_BLOBPROTOCOLHANDLER_CID },
    1063             :   { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX FONTTABLEURI_SCHEME, &kNS_FONTTABLEPROTOCOLHANDLER_CID },
    1064             :   { nullptr }
    1065             : };
    1066             : 
    1067             : static const mozilla::Module kHostObjectProtocolHandlerModule = {
    1068             :   mozilla::Module::kVersion,
    1069             :   kHostObjectProtocolHandlerCIDs,
    1070             :   kHostObjectProtocolHandlerContracts
    1071             : };
    1072             : 
    1073             : NSMODULE_DEFN(HostObjectProtocolHandler) = &kHostObjectProtocolHandlerModule;
    1074             : 
    1075           1 : bool IsType(nsIURI* aUri, DataInfo::ObjectType aType)
    1076             : {
    1077           1 :   DataInfo* info = GetDataInfoFromURI(aUri);
    1078           1 :   if (!info) {
    1079           1 :     return false;
    1080             :   }
    1081             : 
    1082           0 :   return info->mObjectType == aType;
    1083             : }
    1084             : 
    1085           1 : bool IsBlobURI(nsIURI* aUri)
    1086             : {
    1087           1 :   return IsType(aUri, DataInfo::eBlobImpl);
    1088             : }
    1089             : 
    1090           0 : bool IsMediaStreamURI(nsIURI* aUri)
    1091             : {
    1092           0 :   return IsType(aUri, DataInfo::eMediaStream);
    1093             : }
    1094             : 
    1095           0 : bool IsMediaSourceURI(nsIURI* aUri)
    1096             : {
    1097           0 :   return IsType(aUri, DataInfo::eMediaSource);
    1098             : }

Generated by: LCOV version 1.13