Bug 1173467 P1 Modify CacheStorage to reject with SecurityErr instead of throwing on creation. r=ehsan
authorBen Kelly <ben@wanderview.com>
Fri, 26 Jun 2015 19:36:39 -0700
changeset 281256 2aac52b9be3098fae22e614a672f509b3bd5ba83
parent 281255 1524034982b8c7d30298412522ee222af0550b39
child 281257 a7830ef8e7c091f5eaaa152d5e732d95eebcd1fc
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-beta@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs1173467
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1173467 P1 Modify CacheStorage to reject with SecurityErr instead of throwing on creation. r=ehsan
dom/cache/CacheStorage.cpp
dom/cache/CacheStorage.h
--- a/dom/cache/CacheStorage.cpp
+++ b/dom/cache/CacheStorage.cpp
@@ -65,39 +65,40 @@ struct CacheStorage::Entry final
 already_AddRefed<CacheStorage>
 CacheStorage::CreateOnMainThread(Namespace aNamespace, nsIGlobalObject* aGlobal,
                                  nsIPrincipal* aPrincipal, ErrorResult& aRv)
 {
   MOZ_ASSERT(aGlobal);
   MOZ_ASSERT(aPrincipal);
   MOZ_ASSERT(NS_IsMainThread());
 
+
   bool nullPrincipal;
   nsresult rv = aPrincipal->GetIsNullPrincipal(&nullPrincipal);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     aRv.Throw(rv);
     return nullptr;
   }
 
   if (nullPrincipal) {
     NS_WARNING("CacheStorage not supported on null principal.");
-    aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
-    return nullptr;
+    nsRefPtr<CacheStorage> ref = new CacheStorage(NS_ERROR_DOM_SECURITY_ERR);
+    return ref.forget();
   }
 
   // An unknown appId means that this principal was created for the codebase
   // without all the security information from the end document or worker.
   // We require exact knowledge of this information before allowing the
   // caller to touch the disk using the Cache API.
   bool unknownAppId = false;
   aPrincipal->GetUnknownAppId(&unknownAppId);
   if (unknownAppId) {
     NS_WARNING("CacheStorage not supported on principal with unknown appId.");
-    aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
-    return nullptr;
+    nsRefPtr<CacheStorage> ref = new CacheStorage(NS_ERROR_DOM_SECURITY_ERR);
+    return ref.forget();
   }
 
   PrincipalInfo principalInfo;
   rv = PrincipalToPrincipalInfo(aPrincipal, &principalInfo);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     aRv.Throw(rv);
     return nullptr;
   }
@@ -121,41 +122,41 @@ CacheStorage::CreateOnWorker(Namespace a
     NS_WARNING("Worker thread is shutting down.");
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   const PrincipalInfo& principalInfo = aWorkerPrivate->GetPrincipalInfo();
   if (principalInfo.type() == PrincipalInfo::TNullPrincipalInfo) {
     NS_WARNING("CacheStorage not supported on null principal.");
-    aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
-    return nullptr;
+    nsRefPtr<CacheStorage> ref = new CacheStorage(NS_ERROR_DOM_SECURITY_ERR);
+    return ref.forget();
   }
 
   if (principalInfo.type() == PrincipalInfo::TContentPrincipalInfo &&
       principalInfo.get_ContentPrincipalInfo().appId() ==
       nsIScriptSecurityManager::UNKNOWN_APP_ID) {
     NS_WARNING("CacheStorage not supported on principal with unknown appId.");
-    aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
-    return nullptr;
+    nsRefPtr<CacheStorage> ref = new CacheStorage(NS_ERROR_DOM_SECURITY_ERR);
+    return ref.forget();
   }
 
   nsRefPtr<CacheStorage> ref = new CacheStorage(aNamespace, aGlobal,
                                                 principalInfo, feature);
   return ref.forget();
 }
 
 CacheStorage::CacheStorage(Namespace aNamespace, nsIGlobalObject* aGlobal,
                            const PrincipalInfo& aPrincipalInfo, Feature* aFeature)
   : mNamespace(aNamespace)
   , mGlobal(aGlobal)
   , mPrincipalInfo(MakeUnique<PrincipalInfo>(aPrincipalInfo))
   , mFeature(aFeature)
   , mActor(nullptr)
-  , mFailedActor(false)
+  , mStatus(NS_OK)
 {
   MOZ_ASSERT(mGlobal);
 
   // If the PBackground actor is already initialized then we can
   // immediately use it
   PBackgroundChild* actor = BackgroundChild::GetForCurrentThread();
   if (actor) {
     ActorCreated(actor);
@@ -166,24 +167,32 @@ CacheStorage::CacheStorage(Namespace aNa
   // wait for the async ActorCreated() callback.
   MOZ_ASSERT(NS_IsMainThread());
   bool ok = BackgroundChild::GetOrCreateForCurrentThread(this);
   if (NS_WARN_IF(!ok)) {
     ActorFailed();
   }
 }
 
+CacheStorage::CacheStorage(nsresult aFailureResult)
+  : mNamespace(INVALID_NAMESPACE)
+  , mActor(nullptr)
+  , mStatus(aFailureResult)
+{
+  MOZ_ASSERT(NS_FAILED(mStatus));
+}
+
 already_AddRefed<Promise>
 CacheStorage::Match(const RequestOrUSVString& aRequest,
                     const CacheQueryOptions& aOptions, ErrorResult& aRv)
 {
   NS_ASSERT_OWNINGTHREAD(CacheStorage);
 
-  if (NS_WARN_IF(mFailedActor)) {
-    aRv.Throw(NS_ERROR_UNEXPECTED);
+  if (NS_WARN_IF(NS_FAILED(mStatus))) {
+    aRv.Throw(mStatus);
     return nullptr;
   }
 
   nsRefPtr<InternalRequest> request = ToInternalRequest(aRequest, IgnoreBody,
                                                         aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
@@ -207,18 +216,18 @@ CacheStorage::Match(const RequestOrUSVSt
   return promise.forget();
 }
 
 already_AddRefed<Promise>
 CacheStorage::Has(const nsAString& aKey, ErrorResult& aRv)
 {
   NS_ASSERT_OWNINGTHREAD(CacheStorage);
 
-  if (NS_WARN_IF(mFailedActor)) {
-    aRv.Throw(NS_ERROR_UNEXPECTED);
+  if (NS_WARN_IF(NS_FAILED(mStatus))) {
+    aRv.Throw(mStatus);
     return nullptr;
   }
 
   nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
   if (NS_WARN_IF(!promise)) {
     return nullptr;
   }
 
@@ -232,18 +241,18 @@ CacheStorage::Has(const nsAString& aKey,
   return promise.forget();
 }
 
 already_AddRefed<Promise>
 CacheStorage::Open(const nsAString& aKey, ErrorResult& aRv)
 {
   NS_ASSERT_OWNINGTHREAD(CacheStorage);
 
-  if (NS_WARN_IF(mFailedActor)) {
-    aRv.Throw(NS_ERROR_UNEXPECTED);
+  if (NS_WARN_IF(NS_FAILED(mStatus))) {
+    aRv.Throw(mStatus);
     return nullptr;
   }
 
   nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
   if (NS_WARN_IF(!promise)) {
     return nullptr;
   }
 
@@ -257,18 +266,18 @@ CacheStorage::Open(const nsAString& aKey
   return promise.forget();
 }
 
 already_AddRefed<Promise>
 CacheStorage::Delete(const nsAString& aKey, ErrorResult& aRv)
 {
   NS_ASSERT_OWNINGTHREAD(CacheStorage);
 
-  if (NS_WARN_IF(mFailedActor)) {
-    aRv.Throw(NS_ERROR_UNEXPECTED);
+  if (NS_WARN_IF(NS_FAILED(mStatus))) {
+    aRv.Throw(mStatus);
     return nullptr;
   }
 
   nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
   if (NS_WARN_IF(!promise)) {
     return nullptr;
   }
 
@@ -282,18 +291,18 @@ CacheStorage::Delete(const nsAString& aK
   return promise.forget();
 }
 
 already_AddRefed<Promise>
 CacheStorage::Keys(ErrorResult& aRv)
 {
   NS_ASSERT_OWNINGTHREAD(CacheStorage);
 
-  if (NS_WARN_IF(mFailedActor)) {
-    aRv.Throw(NS_ERROR_UNEXPECTED);
+  if (NS_WARN_IF(NS_FAILED(mStatus))) {
+    aRv.Throw(mStatus);
     return nullptr;
   }
 
   nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
   if (NS_WARN_IF(!promise)) {
     return nullptr;
   }
 
@@ -381,19 +390,19 @@ CacheStorage::ActorCreated(PBackgroundCh
   MaybeRunPendingRequests();
   MOZ_ASSERT(mPendingRequests.IsEmpty());
 }
 
 void
 CacheStorage::ActorFailed()
 {
   NS_ASSERT_OWNINGTHREAD(CacheStorage);
-  MOZ_ASSERT(!mFailedActor);
+  MOZ_ASSERT(!NS_FAILED(mStatus));
 
-  mFailedActor = true;
+  mStatus = NS_ERROR_UNEXPECTED;
   mFeature = nullptr;
 
   for (uint32_t i = 0; i < mPendingRequests.Length(); ++i) {
     nsAutoPtr<Entry> entry(mPendingRequests[i].forget());
     entry->mPromise->MaybeReject(NS_ERROR_UNEXPECTED);
   }
   mPendingRequests.Clear();
 }
--- a/dom/cache/CacheStorage.h
+++ b/dom/cache/CacheStorage.h
@@ -89,32 +89,33 @@ public:
 #endif
 
   virtual CachePushStreamChild*
   CreatePushStream(nsIAsyncInputStream* aStream) override;
 
 private:
   CacheStorage(Namespace aNamespace, nsIGlobalObject* aGlobal,
                const mozilla::ipc::PrincipalInfo& aPrincipalInfo, Feature* aFeature);
+  explicit CacheStorage(nsresult aFailureResult);
   ~CacheStorage();
 
   void MaybeRunPendingRequests();
 
   const Namespace mNamespace;
   nsCOMPtr<nsIGlobalObject> mGlobal;
   UniquePtr<mozilla::ipc::PrincipalInfo> mPrincipalInfo;
   nsRefPtr<Feature> mFeature;
 
   // weak ref cleared in DestroyInternal
   CacheStorageChild* mActor;
 
   struct Entry;
   nsTArray<nsAutoPtr<Entry>> mPendingRequests;
 
-  bool mFailedActor;
+  nsresult mStatus;
 
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(CacheStorage,
                                            nsIIPCBackgroundChildCreateCallback)
 };
 
 } // namespace cache