RELEASE_ASSERT(!m_hardClosedForUserDelete) fails in WebCore::IDBServer::UniqueIDBData...
authorsihui_liu@apple.com <sihui_liu@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 8 Nov 2018 01:31:39 +0000 (01:31 +0000)
committersihui_liu@apple.com <sihui_liu@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 8 Nov 2018 01:31:39 +0000 (01:31 +0000)
https://bugs.webkit.org/show_bug.cgi?id=191326
<rdar://problem/45769269>

Reviewed by Geoffrey Garen.

Source/WebCore:

UniqueIDBDatabase should ignore incoming requests or operations when it is already marked as
hardClosedForUserDelete.

Test: IndexedDB.IndexedDBUserDelete.

* Modules/indexeddb/server/UniqueIDBDatabase.cpp:
(WebCore::IDBServer::UniqueIDBDatabase::didPerformActivateTransactionInBackingStore):
(WebCore::IDBServer::UniqueIDBDatabase::immediateCloseForUserDelete):
* Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp:
(WebCore::IDBServer::UniqueIDBDatabaseConnection::establishTransaction):
(WebCore::IDBServer::UniqueIDBDatabaseConnection::deleteTransaction):
* Modules/indexeddb/server/UniqueIDBDatabaseConnection.h:
* Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp:
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::commit):

Tools:

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/IndexedDBUserDelete.html: Added.
* TestWebKitAPI/Tests/WebKitCocoa/IndexedDBUserDelete.mm: Added.
(-[IndexedDBUserDeleteMessageHandler userContentController:didReceiveScriptMessage:]):
(TEST):

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

Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp
Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp
Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseConnection.h
Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebKitCocoa/IndexedDBUserDelete.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKitCocoa/IndexedDBUserDelete.mm [new file with mode: 0644]

index 0be4257..580a331 100644 (file)
@@ -1,3 +1,26 @@
+2018-11-07  Sihui Liu  <sihui_liu@apple.com>
+
+        RELEASE_ASSERT(!m_hardClosedForUserDelete) fails in WebCore::IDBServer::UniqueIDBDatabase::invokeOperationAndTransactionTimer
+        https://bugs.webkit.org/show_bug.cgi?id=191326
+        <rdar://problem/45769269>
+
+        Reviewed by Geoffrey Garen.
+
+        UniqueIDBDatabase should ignore incoming requests or operations when it is already marked as
+        hardClosedForUserDelete.
+
+        Test: IndexedDB.IndexedDBUserDelete.
+
+        * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabase::didPerformActivateTransactionInBackingStore):
+        (WebCore::IDBServer::UniqueIDBDatabase::immediateCloseForUserDelete):
+        * Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabaseConnection::establishTransaction):
+        (WebCore::IDBServer::UniqueIDBDatabaseConnection::deleteTransaction):
+        * Modules/indexeddb/server/UniqueIDBDatabaseConnection.h:
+        * Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::commit):
+
 2018-11-07  Myles C. Maxfield  <mmaxfield@apple.com>
 
         Positioned text underline can look like a strike-through
index f6c4034..9b26039 100644 (file)
@@ -1614,6 +1614,9 @@ void UniqueIDBDatabase::didPerformActivateTransactionInBackingStore(uint64_t cal
 {
     LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformActivateTransactionInBackingStore");
 
+    if (m_hardClosedForUserDelete)
+        return;
+
     invokeOperationAndTransactionTimer();
 
     performErrorCallback(callbackIdentifier, error);
@@ -1805,6 +1808,8 @@ void UniqueIDBDatabase::immediateCloseForUserDelete()
 
     ASSERT(m_inProgressTransactions.isEmpty());
 
+    for (auto& transaction : m_pendingTransactions)
+        transaction->databaseConnection().deleteTransaction(*transaction);
     m_pendingTransactions.clear();
     m_objectStoreTransactionCounts.clear();
     m_objectStoreWriteTransactions.clear();
index 2a40f52..8caaffc 100644 (file)
@@ -153,10 +153,12 @@ void UniqueIDBDatabaseConnection::establishTransaction(const IDBTransactionInfo&
     // the connection is closing.
     ASSERT(!m_closePending);
 
+    if (!m_database || m_database->hardClosedForUserDelete())
+        return;
+
     Ref<UniqueIDBDatabaseTransaction> transaction = UniqueIDBDatabaseTransaction::create(*this, info);
     m_transactionMap.set(transaction->info().identifier(), &transaction.get());
 
-    ASSERT(m_database);
     m_database->enqueueTransaction(WTFMove(transaction));
 }
 
@@ -239,6 +241,16 @@ bool UniqueIDBDatabaseConnection::connectionIsClosing() const
     return m_closePending;
 }
 
+void UniqueIDBDatabaseConnection::deleteTransaction(UniqueIDBDatabaseTransaction& transaction)
+{
+    LOG(IndexedDB, "UniqueIDBDatabaseConnection::deleteTransaction - %s", transaction.info().loggingString().utf8().data());
+    
+    auto transactionIdentifier = transaction.info().identifier();
+    
+    ASSERT(m_transactionMap.contains(transactionIdentifier));
+    m_transactionMap.remove(transactionIdentifier);
+}
+
 } // namespace IDBServer
 } // namespace WebCore
 
index 3a2564a..93e1fa2 100644 (file)
@@ -84,6 +84,8 @@ public:
 
     bool connectionIsClosing() const;
 
+    void deleteTransaction(UniqueIDBDatabaseTransaction&);
+
 private:
     UniqueIDBDatabaseConnection(UniqueIDBDatabase&, ServerOpenDBRequest&);
 
index f47c3b3..79c5d95 100644 (file)
@@ -111,7 +111,8 @@ void UniqueIDBDatabaseTransaction::commit()
     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
 
     auto database = m_databaseConnection->database();
-    ASSERT(database);
+    if (!database || database->hardClosedForUserDelete())
+        return;
 
     database->commitTransaction(*this, [this, protectedThis](const IDBError& error) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::commit (callback)");
index 2b6c775..48ece3a 100644 (file)
@@ -1,3 +1,17 @@
+2018-11-07  Sihui Liu  <sihui_liu@apple.com>
+
+        RELEASE_ASSERT(!m_hardClosedForUserDelete) fails in WebCore::IDBServer::UniqueIDBDatabase::invokeOperationAndTransactionTimer
+        https://bugs.webkit.org/show_bug.cgi?id=191326
+        <rdar://problem/45769269>
+
+        Reviewed by Geoffrey Garen.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKitCocoa/IndexedDBUserDelete.html: Added.
+        * TestWebKitAPI/Tests/WebKitCocoa/IndexedDBUserDelete.mm: Added.
+        (-[IndexedDBUserDeleteMessageHandler userContentController:didReceiveScriptMessage:]):
+        (TEST):
+
 2018-11-07  Daniel Bates  <dabates@apple.com>
 
         Override +[UIKeyboard isInHardwareKeyboardMode] in WebKitTestRunner and DumpRenderTree
index a2e5925..22d57b4 100644 (file)
                CA5B94D22190C0F40059FE38 /* IndexedDBTempFileSize-1.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CA5B94D02190C0E00059FE38 /* IndexedDBTempFileSize-1.html */; };
                CA5B94D32190C0F40059FE38 /* IndexedDBTempFileSize-2.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CA5B94D12190C0E00059FE38 /* IndexedDBTempFileSize-2.html */; };
                CA5B94D72191005B0059FE38 /* IndexedDBTempFileSize.mm in Sources */ = {isa = PBXBuildFile; fileRef = CA5B94D62191005B0059FE38 /* IndexedDBTempFileSize.mm */; };
+               CA97B394219366600045DF6F /* IndexedDBUserDelete.mm in Sources */ = {isa = PBXBuildFile; fileRef = CA97B3922193663B0045DF6F /* IndexedDBUserDelete.mm */; };
+               CA97B3952193667A0045DF6F /* IndexedDBUserDelete.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CA97B393219366470045DF6F /* IndexedDBUserDelete.html */; };
                CD0BD0A61F79924D001AB2CF /* ContextMenuImgWithVideo.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD0BD0A51F799220001AB2CF /* ContextMenuImgWithVideo.mm */; };
                CD0BD0A81F79982D001AB2CF /* ContextMenuImgWithVideo.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CD0BD0A71F7997C2001AB2CF /* ContextMenuImgWithVideo.html */; };
                CD227E44211A4D5D00D285AF /* PreferredAudioBufferSize.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD227E43211A4D5D00D285AF /* PreferredAudioBufferSize.mm */; };
                                57599E2B1F071AA000A3FB8C /* IndexedDBStructuredCloneBackwardCompatibilityWrite.html in Copy Resources */,
                                CA5B94D22190C0F40059FE38 /* IndexedDBTempFileSize-1.html in Copy Resources */,
                                CA5B94D32190C0F40059FE38 /* IndexedDBTempFileSize-2.html in Copy Resources */,
+                               CA97B3952193667A0045DF6F /* IndexedDBUserDelete.html in Copy Resources */,
                                5110FCF91E01CD8A006F8D0B /* IndexUpgrade.blob in Copy Resources */,
                                5110FCF61E01CD83006F8D0B /* IndexUpgrade.sqlite3 in Copy Resources */,
                                2EFF06CD1D8A429A0004BB30 /* input-field-in-scrollable-document.html in Copy Resources */,
                CA5B94D02190C0E00059FE38 /* IndexedDBTempFileSize-1.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "IndexedDBTempFileSize-1.html"; sourceTree = "<group>"; };
                CA5B94D12190C0E00059FE38 /* IndexedDBTempFileSize-2.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "IndexedDBTempFileSize-2.html"; sourceTree = "<group>"; };
                CA5B94D62191005B0059FE38 /* IndexedDBTempFileSize.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = IndexedDBTempFileSize.mm; sourceTree = "<group>"; };
+               CA97B3922193663B0045DF6F /* IndexedDBUserDelete.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = IndexedDBUserDelete.mm; sourceTree = "<group>"; };
+               CA97B393219366470045DF6F /* IndexedDBUserDelete.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = IndexedDBUserDelete.html; sourceTree = "<group>"; };
                CD0BD0A51F799220001AB2CF /* ContextMenuImgWithVideo.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ContextMenuImgWithVideo.mm; sourceTree = "<group>"; };
                CD0BD0A71F7997C2001AB2CF /* ContextMenuImgWithVideo.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = ContextMenuImgWithVideo.html; sourceTree = "<group>"; };
                CD225C071C45A69200140761 /* ParsedContentRange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParsedContentRange.cpp; sourceTree = "<group>"; };
                                51B1EE8D1C80F5880064FB98 /* IndexedDBPersistence.mm */,
                                57599E201F07191700A3FB8C /* IndexedDBStructuredCloneBackwardCompatibility.mm */,
                                CA5B94D62191005B0059FE38 /* IndexedDBTempFileSize.mm */,
+                               CA97B3922193663B0045DF6F /* IndexedDBUserDelete.mm */,
                                0E404A8A2166DDF8008271BA /* InjectedBundleNodeHandleIsSelectElement.mm */,
                                79C5D430209D768300F1E7CA /* InjectedBundleNodeHandleIsTextField.mm */,
                                2DB0232E1E4E871800707123 /* InteractionDeadlockAfterCrash.mm */,
                                57599E231F07192C00A3FB8C /* IndexedDBStructuredCloneBackwardCompatibilityWrite.html */,
                                CA5B94D02190C0E00059FE38 /* IndexedDBTempFileSize-1.html */,
                                CA5B94D12190C0E00059FE38 /* IndexedDBTempFileSize-2.html */,
+                               CA97B393219366470045DF6F /* IndexedDBUserDelete.html */,
                                5110FCF21E01CD77006F8D0B /* IndexUpgrade.blob */,
                                5110FCF31E01CD77006F8D0B /* IndexUpgrade.sqlite3 */,
                                2EFF06CC1D8A42910004BB30 /* input-field-in-scrollable-document.html */,
                                7C83E0BF1D0A652200FEBCF3 /* IndexedDBPersistence.mm in Sources */,
                                57599E211F07191900A3FB8C /* IndexedDBStructuredCloneBackwardCompatibility.mm in Sources */,
                                CA5B94D72191005B0059FE38 /* IndexedDBTempFileSize.mm in Sources */,
+                               CA97B394219366600045DF6F /* IndexedDBUserDelete.mm in Sources */,
                                7A95BDE11E9BEC5F00865498 /* InjectedBundleAppleEvent.cpp in Sources */,
                                7CCE7EFB1A411AE600447C4C /* InjectedBundleBasic.cpp in Sources */,
                                83148B06202AC6A400BADE99 /* InjectedBundleDisableOverrideBuiltinsBehavior.cpp in Sources */,
diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/IndexedDBUserDelete.html b/Tools/TestWebKitAPI/Tests/WebKitCocoa/IndexedDBUserDelete.html
new file mode 100644 (file)
index 0000000..ffb610e
--- /dev/null
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<script>
+
+var request = window.indexedDB.open("IndexedDBUserDelete");
+request.onsuccess = function(event) {
+    window.webkit.messageHandlers.testHandler.postMessage("Continue");
+
+    for (let i = 0; i < 1000; i++) {
+        transaction = event.target.result.transaction("TestObjectStore");
+    }
+}
+
+request.onupgradeneeded = function(event) {
+    var createRequest = event.target.result.createObjectStore("TestObjectStore");
+    createRequest.onerror = function(event) {
+        window.webkit.messageHandlers.testHandler.postMessage("ObjectStore Error");
+    }
+}
+
+request.onerror = function(event) {
+    window.webkit.messageHandlers.testHandler.postMessage("Error");
+}
+
+</script>
\ No newline at end of file
diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/IndexedDBUserDelete.mm b/Tools/TestWebKitAPI/Tests/WebKitCocoa/IndexedDBUserDelete.mm
new file mode 100644 (file)
index 0000000..ae61ef8
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+
+#import "PlatformUtilities.h"
+#import "Test.h"
+
+#import <WebKit/WKProcessPoolPrivate.h>
+#import <WebKit/WKUserContentControllerPrivate.h>
+#import <WebKit/WKWebViewConfigurationPrivate.h>
+#import <WebKit/WebKit.h>
+#import <WebKit/_WKProcessPoolConfiguration.h>
+#import <WebKit/_WKUserStyleSheet.h>
+#import <wtf/RetainPtr.h>
+
+#if WK_API_ENABLED
+
+static bool readyToContinue;
+static bool receivedScriptMessage;
+static RetainPtr<WKScriptMessage> lastScriptMessage;
+
+@interface IndexedDBUserDeleteMessageHandler : NSObject <WKScriptMessageHandler>
+@end
+
+@implementation IndexedDBUserDeleteMessageHandler
+
+- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
+{
+    receivedScriptMessage = true;
+    lastScriptMessage = message;
+}
+
+@end
+
+TEST(IndexedDB, IndexedDBUserDelete)
+{
+    auto handler = adoptNS([[IndexedDBUserDeleteMessageHandler alloc] init]);
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"testHandler"];
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+
+    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"IndexedDBUserDelete" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+    [webView loadRequest:request];
+
+    receivedScriptMessage = false;
+    TestWebKitAPI::Util::run(&receivedScriptMessage);
+    RetainPtr<NSString> string = (NSString *)[lastScriptMessage body];
+
+    [configuration.get().websiteDataStore removeDataOfTypes:[NSSet setWithObjects:WKWebsiteDataTypeIndexedDBDatabases, nil] modifiedSince:[NSDate distantPast] completionHandler:^() {
+        readyToContinue = true;
+    }];
+    readyToContinue = false;
+    TestWebKitAPI::Util::run(&readyToContinue);
+
+    EXPECT_WK_STREQ(@"Continue", string.get());
+}
+
+#endif