tor-browser

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

ServiceWorkerRegistrationDescriptor.cpp (8870B)


      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 "mozilla/dom/ServiceWorkerRegistrationDescriptor.h"
      8 
      9 #include "ServiceWorkerInfo.h"
     10 #include "mozilla/dom/IPCServiceWorkerRegistrationDescriptor.h"
     11 #include "mozilla/ipc/PBackgroundSharedTypes.h"
     12 
     13 namespace mozilla::dom {
     14 
     15 using mozilla::ipc::PrincipalInfo;
     16 using mozilla::ipc::PrincipalInfoToPrincipal;
     17 
     18 Maybe<IPCServiceWorkerDescriptor>
     19 ServiceWorkerRegistrationDescriptor::NewestInternal() const {
     20  Maybe<IPCServiceWorkerDescriptor> result;
     21  if (mData->installing().isSome()) {
     22    result.emplace(mData->installing().ref());
     23  } else if (mData->waiting().isSome()) {
     24    result.emplace(mData->waiting().ref());
     25  } else if (mData->active().isSome()) {
     26    result.emplace(mData->active().ref());
     27  }
     28  return result;
     29 }
     30 
     31 ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor(
     32    uint64_t aId, uint64_t aVersion, nsIPrincipal* aPrincipal,
     33    const nsACString& aScope, WorkerType aType,
     34    ServiceWorkerUpdateViaCache aUpdateViaCache)
     35    : mData(MakeUnique<IPCServiceWorkerRegistrationDescriptor>()) {
     36  MOZ_ALWAYS_SUCCEEDS(
     37      PrincipalToPrincipalInfo(aPrincipal, &mData->principalInfo()));
     38 
     39  mData->id() = aId;
     40  mData->version() = aVersion;
     41  mData->scope() = aScope;
     42  mData->type() = aType;
     43  mData->updateViaCache() = aUpdateViaCache;
     44  mData->installing() = Nothing();
     45  mData->waiting() = Nothing();
     46  mData->active() = Nothing();
     47 }
     48 
     49 ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor(
     50    uint64_t aId, uint64_t aVersion,
     51    const mozilla::ipc::PrincipalInfo& aPrincipalInfo, const nsACString& aScope,
     52    WorkerType aType, ServiceWorkerUpdateViaCache aUpdateViaCache)
     53    : mData(MakeUnique<IPCServiceWorkerRegistrationDescriptor>(
     54          aId, aVersion, aPrincipalInfo, nsCString(aScope), aType,
     55          aUpdateViaCache, Nothing(), Nothing(), Nothing())) {}
     56 
     57 ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor(
     58    const IPCServiceWorkerRegistrationDescriptor& aDescriptor)
     59    : mData(MakeUnique<IPCServiceWorkerRegistrationDescriptor>(aDescriptor)) {
     60 #ifndef FUZZING_SNAPSHOT
     61  MOZ_DIAGNOSTIC_ASSERT(IsValid());
     62 #endif
     63 }
     64 
     65 ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor(
     66    const ServiceWorkerRegistrationDescriptor& aRight) {
     67  // UniquePtr doesn't have a default copy constructor, so we can't rely
     68  // on default copy construction.  Use the assignment operator to
     69  // minimize duplication.
     70  operator=(aRight);
     71 }
     72 
     73 ServiceWorkerRegistrationDescriptor&
     74 ServiceWorkerRegistrationDescriptor::operator=(
     75    const ServiceWorkerRegistrationDescriptor& aRight) {
     76  if (this == &aRight) {
     77    return *this;
     78  }
     79  mData.reset();
     80  mData = MakeUnique<IPCServiceWorkerRegistrationDescriptor>(*aRight.mData);
     81  MOZ_DIAGNOSTIC_ASSERT(IsValid());
     82  return *this;
     83 }
     84 
     85 ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor(
     86    ServiceWorkerRegistrationDescriptor&& aRight)
     87    : mData(std::move(aRight.mData)) {
     88  MOZ_DIAGNOSTIC_ASSERT(IsValid());
     89 }
     90 
     91 ServiceWorkerRegistrationDescriptor&
     92 ServiceWorkerRegistrationDescriptor::operator=(
     93    ServiceWorkerRegistrationDescriptor&& aRight) {
     94  mData.reset();
     95  mData = std::move(aRight.mData);
     96  MOZ_DIAGNOSTIC_ASSERT(IsValid());
     97  return *this;
     98 }
     99 
    100 ServiceWorkerRegistrationDescriptor::~ServiceWorkerRegistrationDescriptor() {
    101  // Non-default destructor to avoid exposing the IPC type in the header.
    102 }
    103 
    104 bool ServiceWorkerRegistrationDescriptor::operator==(
    105    const ServiceWorkerRegistrationDescriptor& aRight) const {
    106  return *mData == *aRight.mData;
    107 }
    108 
    109 uint64_t ServiceWorkerRegistrationDescriptor::Id() const { return mData->id(); }
    110 
    111 uint64_t ServiceWorkerRegistrationDescriptor::Version() const {
    112  return mData->version();
    113 }
    114 
    115 ServiceWorkerUpdateViaCache
    116 ServiceWorkerRegistrationDescriptor::UpdateViaCache() const {
    117  return mData->updateViaCache();
    118 }
    119 
    120 const mozilla::ipc::PrincipalInfo&
    121 ServiceWorkerRegistrationDescriptor::PrincipalInfo() const {
    122  return mData->principalInfo();
    123 }
    124 
    125 Result<nsCOMPtr<nsIPrincipal>, nsresult>
    126 ServiceWorkerRegistrationDescriptor::GetPrincipal() const {
    127  AssertIsOnMainThread();
    128  return PrincipalInfoToPrincipal(mData->principalInfo());
    129 }
    130 
    131 const nsCString& ServiceWorkerRegistrationDescriptor::Scope() const {
    132  return mData->scope();
    133 }
    134 
    135 WorkerType ServiceWorkerRegistrationDescriptor::Type() const {
    136  return mData->type();
    137 }
    138 
    139 Maybe<ServiceWorkerDescriptor>
    140 ServiceWorkerRegistrationDescriptor::GetInstalling() const {
    141  Maybe<ServiceWorkerDescriptor> result;
    142 
    143  if (mData->installing().isSome()) {
    144    result.emplace(ServiceWorkerDescriptor(mData->installing().ref()));
    145  }
    146 
    147  return result;
    148 }
    149 
    150 Maybe<ServiceWorkerDescriptor> ServiceWorkerRegistrationDescriptor::GetWaiting()
    151    const {
    152  Maybe<ServiceWorkerDescriptor> result;
    153 
    154  if (mData->waiting().isSome()) {
    155    result.emplace(ServiceWorkerDescriptor(mData->waiting().ref()));
    156  }
    157 
    158  return result;
    159 }
    160 
    161 Maybe<ServiceWorkerDescriptor> ServiceWorkerRegistrationDescriptor::GetActive()
    162    const {
    163  Maybe<ServiceWorkerDescriptor> result;
    164 
    165  if (mData->active().isSome()) {
    166    result.emplace(ServiceWorkerDescriptor(mData->active().ref()));
    167  }
    168 
    169  return result;
    170 }
    171 
    172 Maybe<ServiceWorkerDescriptor> ServiceWorkerRegistrationDescriptor::Newest()
    173    const {
    174  Maybe<ServiceWorkerDescriptor> result;
    175  Maybe<IPCServiceWorkerDescriptor> newest(NewestInternal());
    176  if (newest.isSome()) {
    177    result.emplace(ServiceWorkerDescriptor(newest.ref()));
    178  }
    179  return result;
    180 }
    181 
    182 bool ServiceWorkerRegistrationDescriptor::HasWorker(
    183    const ServiceWorkerDescriptor& aDescriptor) const {
    184  Maybe<ServiceWorkerDescriptor> installing = GetInstalling();
    185  Maybe<ServiceWorkerDescriptor> waiting = GetWaiting();
    186  Maybe<ServiceWorkerDescriptor> active = GetActive();
    187  return (installing.isSome() && installing.ref().Matches(aDescriptor)) ||
    188         (waiting.isSome() && waiting.ref().Matches(aDescriptor)) ||
    189         (active.isSome() && active.ref().Matches(aDescriptor));
    190 }
    191 
    192 namespace {
    193 
    194 bool IsValidWorker(
    195    const Maybe<IPCServiceWorkerDescriptor>& aWorker, const nsACString& aScope,
    196    const mozilla::ipc::ContentPrincipalInfo& aContentPrincipal) {
    197  if (aWorker.isNothing()) {
    198    return true;
    199  }
    200 
    201  auto& worker = aWorker.ref();
    202  if (worker.scope() != aScope) {
    203    return false;
    204  }
    205 
    206  auto& principalInfo = worker.principalInfo();
    207  if (principalInfo.type() !=
    208      mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) {
    209    return false;
    210  }
    211 
    212  auto& contentPrincipal = principalInfo.get_ContentPrincipalInfo();
    213  if (contentPrincipal.originNoSuffix() != aContentPrincipal.originNoSuffix() ||
    214      contentPrincipal.attrs() != aContentPrincipal.attrs()) {
    215    return false;
    216  }
    217 
    218  return true;
    219 }
    220 
    221 }  // anonymous namespace
    222 
    223 bool ServiceWorkerRegistrationDescriptor::IsValid() const {
    224  auto& principalInfo = PrincipalInfo();
    225  if (principalInfo.type() !=
    226      mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) {
    227    return false;
    228  }
    229 
    230  auto& contentPrincipal = principalInfo.get_ContentPrincipalInfo();
    231  if (!IsValidWorker(mData->installing(), Scope(), contentPrincipal) ||
    232      !IsValidWorker(mData->waiting(), Scope(), contentPrincipal) ||
    233      !IsValidWorker(mData->active(), Scope(), contentPrincipal)) {
    234    return false;
    235  }
    236 
    237  return true;
    238 }
    239 
    240 void ServiceWorkerRegistrationDescriptor::SetUpdateViaCache(
    241    ServiceWorkerUpdateViaCache aUpdateViaCache) {
    242  mData->updateViaCache() = aUpdateViaCache;
    243 }
    244 
    245 void ServiceWorkerRegistrationDescriptor::SetWorkerType(WorkerType aType) {
    246  mData->type() = aType;
    247 }
    248 
    249 void ServiceWorkerRegistrationDescriptor::SetWorkers(
    250    ServiceWorkerInfo* aInstalling, ServiceWorkerInfo* aWaiting,
    251    ServiceWorkerInfo* aActive) {
    252  if (aInstalling) {
    253    aInstalling->SetRegistrationVersion(Version());
    254    mData->installing() = Some(aInstalling->Descriptor().ToIPC());
    255  } else {
    256    mData->installing() = Nothing();
    257  }
    258 
    259  if (aWaiting) {
    260    aWaiting->SetRegistrationVersion(Version());
    261    mData->waiting() = Some(aWaiting->Descriptor().ToIPC());
    262  } else {
    263    mData->waiting() = Nothing();
    264  }
    265 
    266  if (aActive) {
    267    aActive->SetRegistrationVersion(Version());
    268    mData->active() = Some(aActive->Descriptor().ToIPC());
    269  } else {
    270    mData->active() = Nothing();
    271  }
    272 
    273  MOZ_DIAGNOSTIC_ASSERT(IsValid());
    274 }
    275 
    276 void ServiceWorkerRegistrationDescriptor::SetVersion(uint64_t aVersion) {
    277  MOZ_DIAGNOSTIC_ASSERT(aVersion > mData->version());
    278  mData->version() = aVersion;
    279 }
    280 
    281 const IPCServiceWorkerRegistrationDescriptor&
    282 ServiceWorkerRegistrationDescriptor::ToIPC() const {
    283  return *mData;
    284 }
    285 
    286 }  // namespace mozilla::dom