Title: [247607] branches/safari-608-branch/Source/WebCore
Revision
247607
Author
kocsen_ch...@apple.com
Date
2019-07-18 13:24:44 -0700 (Thu, 18 Jul 2019)

Log Message

Cherry-pick r247531. rdar://problem/53229712

    IndexedDB: error in starting version change transaction may be neglected
    https://bugs.webkit.org/show_bug.cgi?id=199818
    <rdar://problem/52925738>

    Reviewed by Brady Eidson.

    For version change transaction, IDBServer didn't wait the result of beginTransaction on the background thread
    before giving the IDBClient the result of open request. In this case, beginTransaction may fail to update the
    DatabaseVersion in database file or set m_originalDatabaseInfoBeforeVersionChange, but the transaction was
    marked as started. When we later set m_databaseInfo with m_originalDatabaseInfoBeforeVersionChange,
    m_databaseInfo could become nullptr.

    To write a test for this, we will need to simulate an SQLite error. I manually tested this by crafting the
    SQLiteStatement in beginTransaction, making it an invalid statement, and verified that error event, instead of
    ungradeneeded event is dispatched to the IDBRequest.

    * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
    (WebCore::IDBServer::UniqueIDBDatabase::startVersionChangeTransaction):
    (WebCore::IDBServer::UniqueIDBDatabase::performStartVersionChangeTransaction):
    (WebCore::IDBServer::UniqueIDBDatabase::didPerformStartVersionChangeTransaction):
    (WebCore::IDBServer::UniqueIDBDatabase::beginTransactionInBackingStore): Deleted.
    * Modules/indexeddb/server/UniqueIDBDatabase.h:

    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@247531 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Modified Paths

Diff

Modified: branches/safari-608-branch/Source/WebCore/ChangeLog (247606 => 247607)


--- branches/safari-608-branch/Source/WebCore/ChangeLog	2019-07-18 20:24:40 UTC (rev 247606)
+++ branches/safari-608-branch/Source/WebCore/ChangeLog	2019-07-18 20:24:44 UTC (rev 247607)
@@ -1,5 +1,60 @@
 2019-07-17  Kocsen Chung  <kocsen_ch...@apple.com>
 
+        Cherry-pick r247531. rdar://problem/53229712
+
+    IndexedDB: error in starting version change transaction may be neglected
+    https://bugs.webkit.org/show_bug.cgi?id=199818
+    <rdar://problem/52925738>
+    
+    Reviewed by Brady Eidson.
+    
+    For version change transaction, IDBServer didn't wait the result of beginTransaction on the background thread
+    before giving the IDBClient the result of open request. In this case, beginTransaction may fail to update the
+    DatabaseVersion in database file or set m_originalDatabaseInfoBeforeVersionChange, but the transaction was
+    marked as started. When we later set m_databaseInfo with m_originalDatabaseInfoBeforeVersionChange,
+    m_databaseInfo could become nullptr.
+    
+    To write a test for this, we will need to simulate an SQLite error. I manually tested this by crafting the
+    SQLiteStatement in beginTransaction, making it an invalid statement, and verified that error event, instead of
+    ungradeneeded event is dispatched to the IDBRequest.
+    
+    * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+    (WebCore::IDBServer::UniqueIDBDatabase::startVersionChangeTransaction):
+    (WebCore::IDBServer::UniqueIDBDatabase::performStartVersionChangeTransaction):
+    (WebCore::IDBServer::UniqueIDBDatabase::didPerformStartVersionChangeTransaction):
+    (WebCore::IDBServer::UniqueIDBDatabase::beginTransactionInBackingStore): Deleted.
+    * Modules/indexeddb/server/UniqueIDBDatabase.h:
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@247531 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2019-07-17  Sihui Liu  <sihui_...@apple.com>
+
+            IndexedDB: error in starting version change transaction may be neglected
+            https://bugs.webkit.org/show_bug.cgi?id=199818
+            <rdar://problem/52925738>
+
+            Reviewed by Brady Eidson.
+
+            For version change transaction, IDBServer didn't wait the result of beginTransaction on the background thread
+            before giving the IDBClient the result of open request. In this case, beginTransaction may fail to update the
+            DatabaseVersion in database file or set m_originalDatabaseInfoBeforeVersionChange, but the transaction was
+            marked as started. When we later set m_databaseInfo with m_originalDatabaseInfoBeforeVersionChange,
+            m_databaseInfo could become nullptr.
+
+            To write a test for this, we will need to simulate an SQLite error. I manually tested this by crafting the
+            SQLiteStatement in beginTransaction, making it an invalid statement, and verified that error event, instead of
+            ungradeneeded event is dispatched to the IDBRequest.
+
+            * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+            (WebCore::IDBServer::UniqueIDBDatabase::startVersionChangeTransaction):
+            (WebCore::IDBServer::UniqueIDBDatabase::performStartVersionChangeTransaction):
+            (WebCore::IDBServer::UniqueIDBDatabase::didPerformStartVersionChangeTransaction):
+            (WebCore::IDBServer::UniqueIDBDatabase::beginTransactionInBackingStore): Deleted.
+            * Modules/indexeddb/server/UniqueIDBDatabase.h:
+
+2019-07-17  Kocsen Chung  <kocsen_ch...@apple.com>
+
         Cherry-pick r247530. rdar://problem/53229569
 
     Typing into a cell in a Google Sheet lags behind by one character

Modified: branches/safari-608-branch/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp (247606 => 247607)


--- branches/safari-608-branch/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp	2019-07-18 20:24:40 UTC (rev 247606)
+++ branches/safari-608-branch/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp	2019-07-18 20:24:44 UTC (rev 247607)
@@ -628,28 +628,46 @@
     ASSERT(m_currentOpenDBRequest->isOpenRequest());
     ASSERT(m_versionChangeDatabaseConnection);
 
-    auto operation = WTFMove(m_currentOpenDBRequest);
-
-    uint64_t requestedVersion = operation->requestData().requestedVersion();
+    uint64_t requestedVersion = m_currentOpenDBRequest->requestData().requestedVersion();
     if (!requestedVersion)
         requestedVersion = m_databaseInfo->version() ? m_databaseInfo->version() : 1;
 
-    addOpenDatabaseConnection(*m_versionChangeDatabaseConnection);
-
     m_versionChangeTransaction = &m_versionChangeDatabaseConnection->createVersionChangeTransaction(requestedVersion);
-    m_databaseInfo->setVersion(requestedVersion);
 
-    m_inProgressTransactions.set(m_versionChangeTransaction->info().identifier(), m_versionChangeTransaction);
-    postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::beginTransactionInBackingStore, m_versionChangeTransaction->info()));
+    postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performStartVersionChangeTransaction, m_versionChangeTransaction->info()));
+}
 
-    auto result = IDBResultData::openDatabaseUpgradeNeeded(operation->requestData().requestIdentifier(), *m_versionChangeTransaction);
-    operation->connection().didOpenDatabase(result);
+void UniqueIDBDatabase::performStartVersionChangeTransaction(const IDBTransactionInfo& info)
+{
+    LOG(IndexedDB, "(db) UniqueIDBDatabase::performStartVersionChangeTransaction");
+
+    IDBError error = m_backingStore->beginTransaction(info);
+    postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformStartVersionChangeTransaction, error));
 }
 
-void UniqueIDBDatabase::beginTransactionInBackingStore(const IDBTransactionInfo& info)
+void UniqueIDBDatabase::didPerformStartVersionChangeTransaction(const IDBError& error)
 {
-    LOG(IndexedDB, "(db) UniqueIDBDatabase::beginTransactionInBackingStore");
-    m_backingStore->beginTransaction(info);
+    LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformStartVersionChangeTransaction");
+
+    if (m_hardClosedForUserDelete)
+        return;
+
+    auto operation = WTFMove(m_currentOpenDBRequest);
+    IDBResultData result;
+    if (error.isNull()) {
+        addOpenDatabaseConnection(*m_versionChangeDatabaseConnection);
+        m_databaseInfo->setVersion(m_versionChangeTransaction->info().newVersion());
+        m_inProgressTransactions.set(m_versionChangeTransaction->info().identifier(), m_versionChangeTransaction);
+        result = IDBResultData::openDatabaseUpgradeNeeded(operation->requestData().requestIdentifier(), *m_versionChangeTransaction);
+        operation->connection().didOpenDatabase(result);
+    } else {
+        m_versionChangeTransaction = nullptr;
+        m_versionChangeDatabaseConnection = nullptr;
+        result = IDBResultData::error(operation->requestData().requestIdentifier(), error);
+        operation->connection().didOpenDatabase(result);
+    }
+
+    invokeOperationAndTransactionTimer();
 }
 
 void UniqueIDBDatabase::maybeNotifyConnectionsOfVersionChange()

Modified: branches/safari-608-branch/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h (247606 => 247607)


--- branches/safari-608-branch/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h	2019-07-18 20:24:40 UTC (rev 247606)
+++ branches/safari-608-branch/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h	2019-07-18 20:24:44 UTC (rev 247607)
@@ -191,6 +191,7 @@
     void performIterateCursor(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBResourceIdentifier& cursorIdentifier, const IDBIterateCursorData&);
     void performPrefetchCursor(const IDBResourceIdentifier& transactionIdentifier, const IDBResourceIdentifier& cursorIdentifier);
 
+    void performStartVersionChangeTransaction(const IDBTransactionInfo&);
     void performActivateTransactionInBackingStore(uint64_t callbackIdentifier, const IDBTransactionInfo&);
     void performUnconditionalDeleteBackingStore();
     void shutdownForClose();
@@ -214,6 +215,8 @@
     void didPerformIterateCursor(uint64_t callbackIdentifier, const IDBError&, const IDBGetResult&);
     void didPerformCommitTransaction(uint64_t callbackIdentifier, const IDBError&, const IDBResourceIdentifier& transactionIdentifier);
     void didPerformAbortTransaction(uint64_t callbackIdentifier, const IDBError&, const IDBResourceIdentifier& transactionIdentifier);
+
+    void didPerformStartVersionChangeTransaction(const IDBError&);
     void didPerformActivateTransactionInBackingStore(uint64_t callbackIdentifier, const IDBError&);
     void didPerformUnconditionalDeleteBackingStore();
     void didShutdownForClose();
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to