IndexedDB: Protect against key prefix overflows
[WebKit-https.git] / Source / WebCore / Modules / indexeddb / IDBDatabaseBackendImpl.cpp
index 2c30320..76d8368 100644 (file)
@@ -179,22 +179,22 @@ private:
 
 class DeleteIndexOperation : public IDBTransactionBackendImpl::Operation {
 public:
-    static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBBackingStore> backingStore, int64_t objectStoreId, int64_t indexId)
+    static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBBackingStore> backingStore, int64_t objectStoreId, const IDBIndexMetadata& indexMetadata)
     {
-        return adoptPtr(new DeleteIndexOperation(backingStore, objectStoreId, indexId));
+        return adoptPtr(new DeleteIndexOperation(backingStore, objectStoreId, indexMetadata));
     }
     virtual void perform(IDBTransactionBackendImpl*);
 private:
-    DeleteIndexOperation(PassRefPtr<IDBBackingStore> backingStore, int64_t objectStoreId, int64_t indexId)
+    DeleteIndexOperation(PassRefPtr<IDBBackingStore> backingStore, int64_t objectStoreId, const IDBIndexMetadata& indexMetadata)
         : m_backingStore(backingStore)
         , m_objectStoreId(objectStoreId)
-        , m_indexId(indexId)
+        , m_indexMetadata(indexMetadata)
     {
     }
 
     const RefPtr<IDBBackingStore> m_backingStore;
     const int64_t m_objectStoreId;
-    const int64_t m_indexId;
+    const IDBIndexMetadata m_indexMetadata;
 };
 
 class CreateIndexAbortOperation : public IDBTransactionBackendImpl::Operation {
@@ -534,10 +534,9 @@ bool IDBDatabaseBackendImpl::openInternal()
     ASSERT_WITH_MESSAGE(success == (m_metadata.id != InvalidId), "success = %s, m_id = %lld", success ? "true" : "false", static_cast<long long>(m_metadata.id));
     if (!ok)
         return false;
-    if (success) {
-        m_backingStore->getObjectStores(m_metadata.id, &m_metadata.objectStores);
-        return true;
-    }
+    if (success)
+        return m_backingStore->getObjectStores(m_metadata.id, &m_metadata.objectStores);
+
     return m_backingStore->createIDBDatabaseMetaData(m_metadata.name, m_metadata.version, m_metadata.intVersion, m_metadata.id);
 }
 
@@ -640,7 +639,7 @@ void IDBDatabaseBackendImpl::deleteIndex(int64_t transactionId, int64_t objectSt
     ASSERT(objectStore.indexes.contains(indexId));
     const IDBIndexMetadata& indexMetadata = objectStore.indexes.get(indexId);
 
-    transaction->scheduleTask(DeleteIndexOperation::create(m_backingStore, objectStoreId, indexId), DeleteIndexAbortOperation::create(this, objectStoreId, indexMetadata));
+    transaction->scheduleTask(DeleteIndexOperation::create(m_backingStore, objectStoreId, indexMetadata), DeleteIndexAbortOperation::create(this, objectStoreId, indexMetadata));
 
     removeIndex(objectStoreId, indexId);
 }
@@ -648,7 +647,11 @@ void IDBDatabaseBackendImpl::deleteIndex(int64_t transactionId, int64_t objectSt
 void DeleteIndexOperation::perform(IDBTransactionBackendImpl* transaction)
 {
     IDB_TRACE("DeleteIndexOperation");
-    m_backingStore->deleteIndex(transaction->backingStoreTransaction(), transaction->database()->id(), m_objectStoreId, m_indexId);
+    bool ok = m_backingStore->deleteIndex(transaction->backingStoreTransaction(), transaction->database()->id(), m_objectStoreId, m_indexMetadata.id);
+    if (!ok) {
+        RefPtr<IDBDatabaseError> error = IDBDatabaseError::create(IDBDatabaseException::UnknownError, String::format("Internal error deleting index '%s'.", m_indexMetadata.name.utf8().data()));
+        transaction->abort(error);
+    }
 }
 
 void DeleteIndexAbortOperation::perform(IDBTransactionBackendImpl* transaction)
@@ -1023,7 +1026,10 @@ void DeleteRangeOperation::perform(IDBTransactionBackendImpl* transaction)
     RefPtr<IDBBackingStore::Cursor> backingStoreCursor = m_backingStore->openObjectStoreCursor(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, m_keyRange.get(), IndexedDB::CursorNext);
     if (backingStoreCursor) {
         do {
-            m_backingStore->deleteRecord(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, backingStoreCursor->recordIdentifier());
+            if (!m_backingStore->deleteRecord(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, backingStoreCursor->recordIdentifier())) {
+                m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Error deleting data in range"));
+                return;
+            }
         } while (backingStoreCursor->continueFunction(0));
     }
 
@@ -1044,7 +1050,10 @@ void IDBDatabaseBackendImpl::clear(int64_t transactionId, int64_t objectStoreId,
 void ClearOperation::perform(IDBTransactionBackendImpl* transaction)
 {
     IDB_TRACE("ObjectStoreClearOperation");
-    m_backingStore->clearObjectStore(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId);
+    if (!m_backingStore->clearObjectStore(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId)) {
+        m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Error clearing object store"));
+        return;
+    }
     m_callbacks->onSuccess();
 }