Bug 1149815 - Guard against using deleted IDBObjectStore and IDBIndex objects, r=janv.
authorBen Turner <bent.mozilla@gmail.com>
Sat, 20 Jun 2015 09:08:23 -0700
changeset 280659 826980ade3b28bc856ca32e2f49b1ec2b7a9effa
parent 280658 c6df9bf6c5396ea18dfb373105e7456154bf4f43
child 280660 f270dc49a348c10c91d8efa5d349d44bed7ff407
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)
reviewersjanv
bugs1149815
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 1149815 - Guard against using deleted IDBObjectStore and IDBIndex objects, r=janv.
dom/indexedDB/ActorsParent.cpp
dom/indexedDB/IDBIndex.cpp
dom/indexedDB/IDBObjectStore.cpp
--- a/dom/indexedDB/ActorsParent.cpp
+++ b/dom/indexedDB/ActorsParent.cpp
@@ -13055,22 +13055,22 @@ TransactionBase::GetMetadataForObjectSto
   MOZ_ASSERT(aObjectStoreId);
 
   if (!aObjectStoreId) {
     return nullptr;
   }
 
   nsRefPtr<FullObjectStoreMetadata> metadata;
   if (!mDatabase->Metadata()->mObjectStores.Get(aObjectStoreId,
-                                                getter_AddRefs(metadata))) {
+                                                getter_AddRefs(metadata)) ||
+      metadata->mDeleted) {
     return nullptr;
   }
 
   MOZ_ASSERT(metadata->mCommonMetadata.id() == aObjectStoreId);
-  MOZ_ASSERT(!metadata->mDeleted);
 
   return metadata.forget();
 }
 
 already_AddRefed<FullIndexMetadata>
 TransactionBase::GetMetadataForIndexId(
                             FullObjectStoreMetadata* const aObjectStoreMetadata,
                             int64_t aIndexId) const
@@ -13078,22 +13078,22 @@ TransactionBase::GetMetadataForIndexId(
   AssertIsOnBackgroundThread();
   MOZ_ASSERT(aIndexId);
 
   if (!aIndexId) {
     return nullptr;
   }
 
   nsRefPtr<FullIndexMetadata> metadata;
-  if (!aObjectStoreMetadata->mIndexes.Get(aIndexId, getter_AddRefs(metadata))) {
+  if (!aObjectStoreMetadata->mIndexes.Get(aIndexId, getter_AddRefs(metadata)) ||
+      metadata->mDeleted) {
     return nullptr;
   }
 
   MOZ_ASSERT(metadata->mCommonMetadata.id() == aIndexId);
-  MOZ_ASSERT(!metadata->mDeleted);
 
   return metadata.forget();
 }
 
 void
 TransactionBase::NoteModifiedAutoIncrementObjectStore(
                                              FullObjectStoreMetadata* aMetadata)
 {
--- a/dom/indexedDB/IDBIndex.cpp
+++ b/dom/indexedDB/IDBIndex.cpp
@@ -218,16 +218,21 @@ IDBIndex::GetKeyPath(JSContext* aCx,
 already_AddRefed<IDBRequest>
 IDBIndex::GetInternal(bool aKeyOnly,
                       JSContext* aCx,
                       JS::Handle<JS::Value> aKey,
                       ErrorResult& aRv)
 {
   AssertIsOnOwningThread();
 
+  if (mDeletedMetadata) {
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
+    return nullptr;
+  }
+
   IDBTransaction* transaction = mObjectStore->Transaction();
   if (!transaction->IsOpen()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
     return nullptr;
   }
 
   nsRefPtr<IDBKeyRange> keyRange;
   aRv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
@@ -301,16 +306,21 @@ already_AddRefed<IDBRequest>
 IDBIndex::GetAllInternal(bool aKeysOnly,
                          JSContext* aCx,
                          JS::Handle<JS::Value> aKey,
                          const Optional<uint32_t>& aLimit,
                          ErrorResult& aRv)
 {
   AssertIsOnOwningThread();
 
+  if (mDeletedMetadata) {
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
+    return nullptr;
+  }
+
   IDBTransaction* transaction = mObjectStore->Transaction();
   if (!transaction->IsOpen()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
     return nullptr;
   }
 
   nsRefPtr<IDBKeyRange> keyRange;
   aRv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
@@ -382,16 +392,21 @@ already_AddRefed<IDBRequest>
 IDBIndex::OpenCursorInternal(bool aKeysOnly,
                              JSContext* aCx,
                              JS::Handle<JS::Value> aRange,
                              IDBCursorDirection aDirection,
                              ErrorResult& aRv)
 {
   AssertIsOnOwningThread();
 
+  if (mDeletedMetadata) {
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
+    return nullptr;
+  }
+
   IDBTransaction* transaction = mObjectStore->Transaction();
   if (!transaction->IsOpen()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
     return nullptr;
   }
 
   nsRefPtr<IDBKeyRange> keyRange;
   aRv = IDBKeyRange::FromJSVal(aCx, aRange, getter_AddRefs(keyRange));
@@ -478,16 +493,21 @@ IDBIndex::OpenCursorInternal(bool aKeysO
 
 already_AddRefed<IDBRequest>
 IDBIndex::Count(JSContext* aCx,
                 JS::Handle<JS::Value> aKey,
                 ErrorResult& aRv)
 {
   AssertIsOnOwningThread();
 
+  if (mDeletedMetadata) {
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
+    return nullptr;
+  }
+
   IDBTransaction* transaction = mObjectStore->Transaction();
   if (!transaction->IsOpen()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
     return nullptr;
   }
 
   nsRefPtr<IDBKeyRange> keyRange;
   aRv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -1155,16 +1155,21 @@ IDBObjectStore::AddOrPut(JSContext* aCx,
                          bool aOverwrite,
                          bool aFromCursor,
                          ErrorResult& aRv)
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(aCx);
   MOZ_ASSERT_IF(aFromCursor, aOverwrite);
 
+  if (mDeletedSpec) {
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
+    return nullptr;
+  }
+
   if (!mTransaction->IsOpen()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
     return nullptr;
   }
 
   if (!mTransaction->IsWriteAllowed()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR);
     return nullptr;
@@ -1309,16 +1314,21 @@ already_AddRefed<IDBRequest>
 IDBObjectStore::GetAllInternal(bool aKeysOnly,
                                JSContext* aCx,
                                JS::Handle<JS::Value> aKey,
                                const Optional<uint32_t>& aLimit,
                                ErrorResult& aRv)
 {
   AssertIsOnOwningThread();
 
+  if (mDeletedSpec) {
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
+    return nullptr;
+  }
+
   if (!mTransaction->IsOpen()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
     return nullptr;
   }
 
   nsRefPtr<IDBKeyRange> keyRange;
   aRv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
   if (NS_WARN_IF(aRv.Failed())) {
@@ -1381,16 +1391,21 @@ IDBObjectStore::GetAllInternal(bool aKey
   return request.forget();
 }
 
 already_AddRefed<IDBRequest>
 IDBObjectStore::Clear(ErrorResult& aRv)
 {
   AssertIsOnOwningThread();
 
+  if (mDeletedSpec) {
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
+    return nullptr;
+  }
+
   if (!mTransaction->IsOpen()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
     return nullptr;
   }
 
   if (!mTransaction->IsWriteAllowed()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR);
     return nullptr;
@@ -1567,16 +1582,21 @@ IDBObjectStore::IndexNames()
 
 already_AddRefed<IDBRequest>
 IDBObjectStore::Get(JSContext* aCx,
                     JS::Handle<JS::Value> aKey,
                     ErrorResult& aRv)
 {
   AssertIsOnOwningThread();
 
+  if (mDeletedSpec) {
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
+    return nullptr;
+  }
+
   if (!mTransaction->IsOpen()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
     return nullptr;
   }
 
   nsRefPtr<IDBKeyRange> keyRange;
   aRv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
   if (aRv.Failed()) {
@@ -1615,16 +1635,21 @@ IDBObjectStore::Get(JSContext* aCx,
 already_AddRefed<IDBRequest>
 IDBObjectStore::DeleteInternal(JSContext* aCx,
                                JS::Handle<JS::Value> aKey,
                                bool aFromCursor,
                                ErrorResult& aRv)
 {
   AssertIsOnOwningThread();
 
+  if (mDeletedSpec) {
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
+    return nullptr;
+  }
+
   if (!mTransaction->IsOpen()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
     return nullptr;
   }
 
   if (!mTransaction->IsWriteAllowed()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR);
     return nullptr;
@@ -1712,17 +1737,18 @@ IDBObjectStore::CreateIndexInternal(
                                   ErrorResult& aRv)
 {
   AssertIsOnOwningThread();
 
   IDBTransaction* transaction = IDBTransaction::GetCurrent();
 
   if (!transaction ||
       transaction != mTransaction ||
-      mTransaction->GetMode() != IDBTransaction::VERSION_CHANGE) {
+      mTransaction->GetMode() != IDBTransaction::VERSION_CHANGE ||
+      mDeletedSpec) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
     return nullptr;
   }
 
   MOZ_ASSERT(transaction->IsOpen());
 
   auto& indexes = const_cast<nsTArray<IndexMetadata>&>(mSpec->indexes());
   for (uint32_t count = indexes.Length(), index = 0;
@@ -1792,17 +1818,18 @@ void
 IDBObjectStore::DeleteIndex(const nsAString& aName, ErrorResult& aRv)
 {
   AssertIsOnOwningThread();
 
   IDBTransaction* transaction = IDBTransaction::GetCurrent();
 
   if (!transaction ||
       transaction != mTransaction ||
-      mTransaction->GetMode() != IDBTransaction::VERSION_CHANGE) {
+      mTransaction->GetMode() != IDBTransaction::VERSION_CHANGE ||
+      mDeletedSpec) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
     return;
   }
 
   MOZ_ASSERT(transaction->IsOpen());
 
   auto& metadataArray = const_cast<nsTArray<IndexMetadata>&>(mSpec->indexes());
 
@@ -1861,16 +1888,23 @@ IDBObjectStore::DeleteIndex(const nsAStr
   transaction->DeleteIndex(this, foundId);
 }
 
 already_AddRefed<IDBRequest>
 IDBObjectStore::Count(JSContext* aCx,
                       JS::Handle<JS::Value> aKey,
                       ErrorResult& aRv)
 {
+  AssertIsOnOwningThread();
+
+  if (mDeletedSpec) {
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
+    return nullptr;
+  }
+
   if (!mTransaction->IsOpen()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
     return nullptr;
   }
 
   nsRefPtr<IDBKeyRange> keyRange;
   aRv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
   if (aRv.Failed()) {
@@ -1911,16 +1945,21 @@ already_AddRefed<IDBRequest>
 IDBObjectStore::OpenCursorInternal(bool aKeysOnly,
                                    JSContext* aCx,
                                    JS::Handle<JS::Value> aRange,
                                    IDBCursorDirection aDirection,
                                    ErrorResult& aRv)
 {
   AssertIsOnOwningThread();
 
+  if (mDeletedSpec) {
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
+    return nullptr;
+  }
+
   if (!mTransaction->IsOpen()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
     return nullptr;
   }
 
   nsRefPtr<IDBKeyRange> keyRange;
   aRv = IDBKeyRange::FromJSVal(aCx, aRange, getter_AddRefs(keyRange));
   if (NS_WARN_IF(aRv.Failed())) {