Title: [223758] branches/safari-604-branch

Diff

Modified: branches/safari-604-branch/Source/WebCore/ChangeLog (223757 => 223758)


--- branches/safari-604-branch/Source/WebCore/ChangeLog	2017-10-20 12:45:46 UTC (rev 223757)
+++ branches/safari-604-branch/Source/WebCore/ChangeLog	2017-10-20 15:00:04 UTC (rev 223758)
@@ -1,5 +1,45 @@
 2017-10-19  Jason Marcell  <jmarc...@apple.com>
 
+        Cherry-pick r223427. rdar://problem/34745623
+
+    2017-10-16  Maureen Daum  <md...@apple.com>
+
+            If we fail to delete any database file, don't remove its information from the tracker database
+            <rdar://problem/34576132> and https://bugs.webkit.org/show_bug.cgi?id=178251
+
+            Reviewed by Brady Eidson.
+
+            New tests:
+            DatabaseTracker.DeleteDatabase
+            DatabaseTracker.DeleteDatabaseWhenDatabaseDoesNotExist
+            DatabaseTracker.DeleteOrigin
+            DatabaseTracker.DeleteOriginWhenDeletingADatabaseFails
+            DatabaseTracker.DeleteOriginWhenDatabaseDoesNotExist
+
+            * Modules/webdatabase/DatabaseTracker.cpp:
+            (WebCore::DatabaseTracker::deleteDatabasesModifiedSince):
+            If the database doesn't exist, we previously deleted it but failed to remove the
+            information from the tracker database. We still want to delete all of the information
+            associated with this database from the tracker database, so add it to databaseNamesToDelete.
+            (WebCore::DatabaseTracker::deleteOrigin):
+            If a database doesn't exist, don't try to delete it. We don't need to, but more
+            importantly, deleteDatabaseFile() will fail if the database doesn't exist, which
+            will cause us to incorrectly think we failed to remove database information from disk.
+            If we actually fail to delete any database file, return before we remove the origin
+            information from the tracker database so we don't lose track of the database.
+            (WebCore::DatabaseTracker::deleteDatabase):
+            If a database doesn't exist, don't try to delete it. We don't need to, but also it
+            will cause us to incorrectly think that we were unable to delete a database, so we
+            would bail before we remove the database information from the tracker database. We
+            want to remove the database information from the tracker database because the database
+            doesn't exist.
+            * Modules/webdatabase/DatabaseTracker.h:
+            Expose fullPathForDatabase() for use by tests.
+            * platform/Logging.h:
+            Add a logging channel.
+
+2017-10-19  Jason Marcell  <jmarc...@apple.com>
+
         Cherry-pick r223565. rdar://problem/35041490
 
     2017-10-17  John Wilander  <wilan...@apple.com>

Modified: branches/safari-604-branch/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp (223757 => 223758)


--- branches/safari-604-branch/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp	2017-10-20 12:45:46 UTC (rev 223757)
+++ branches/safari-604-branch/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp	2017-10-20 15:00:04 UTC (rev 223758)
@@ -783,12 +783,17 @@
         for (const auto& databaseName : databaseNames) {
             auto fullPath = fullPathForDatabase(origin, databaseName, false);
 
-            time_t modificationTime;
-            if (!getFileModificationTime(fullPath, modificationTime))
-                continue;
+            // If the file doesn't exist, we previously deleted it but failed to remove the information
+            // from the tracker database. We want to delete all of the information associated with this
+            // database from the tracker database, so still add its name to databaseNamesToDelete.
+            if (fileExists(fullPath)) {
+                time_t modificationTime;
+                if (!getFileModificationTime(fullPath, modificationTime))
+                    continue;
 
-            if (modificationTime < std::chrono::system_clock::to_time_t(time))
-                continue;
+                if (modificationTime < std::chrono::system_clock::to_time_t(time))
+                    continue;
+            }
 
             databaseNamesToDelete.uncheckedAppend(databaseName);
         }
@@ -832,13 +837,22 @@
     }
 
     // We drop the lock here because holding locks during a call to deleteDatabaseFile will deadlock.
+    bool failedToDeleteAnyDatabaseFile = false;
     for (auto& name : databaseNames) {
-        if (!deleteDatabaseFile(origin, name, deletionMode)) {
+        if (fileExists(fullPathForDatabase(origin, name, false)) && !deleteDatabaseFile(origin, name, deletionMode)) {
             // Even if the file can't be deleted, we want to try and delete the rest, don't return early here.
             LOG_ERROR("Unable to delete file for database %s in origin %s", name.utf8().data(), origin.databaseIdentifier().utf8().data());
+            failedToDeleteAnyDatabaseFile = true;
         }
     }
 
+    // If we failed to delete any database file, don't remove the origin from the tracker
+    // database because we didn't successfully remove all of its data.
+    if (failedToDeleteAnyDatabaseFile) {
+        RELEASE_LOG_ERROR(DatabaseTracker, "Failed to delete database for origin");
+        return false;
+    }
+
     {
         LockHolder lockDatabase(m_databaseGuard);
         deleteOriginLockFor(origin);
@@ -1038,7 +1052,7 @@
     }
 
     // We drop the lock here because holding locks during a call to deleteDatabaseFile will deadlock.
-    if (!deleteDatabaseFile(origin, name, DeletionMode::Default)) {
+    if (fileExists(fullPathForDatabase(origin, name, false)) && !deleteDatabaseFile(origin, name, DeletionMode::Default)) {
         LOG_ERROR("Unable to delete file for database %s in origin %s", name.utf8().data(), origin.databaseIdentifier().utf8().data());
         LockHolder lockDatabase(m_databaseGuard);
         doneDeletingDatabase(origin, name);

Modified: branches/safari-604-branch/Source/WebCore/Modules/webdatabase/DatabaseTracker.h (223757 => 223758)


--- branches/safari-604-branch/Source/WebCore/Modules/webdatabase/DatabaseTracker.h	2017-10-20 12:45:46 UTC (rev 223757)
+++ branches/safari-604-branch/Source/WebCore/Modules/webdatabase/DatabaseTracker.h	2017-10-20 15:00:04 UTC (rev 223758)
@@ -69,7 +69,7 @@
     ExceptionOr<void> retryCanEstablishDatabase(DatabaseContext&, const String& name, unsigned estimatedSize);
 
     void setDatabaseDetails(const SecurityOriginData&, const String& name, const String& displayName, unsigned estimatedSize);
-    String fullPathForDatabase(const SecurityOriginData&, const String& name, bool createIfDoesNotExist);
+    WEBCORE_EXPORT String fullPathForDatabase(const SecurityOriginData&, const String& name, bool createIfDoesNotExist);
 
     void addOpenDatabase(Database&);
     void removeOpenDatabase(Database&);

Modified: branches/safari-604-branch/Source/WebCore/platform/Logging.h (223757 => 223758)


--- branches/safari-604-branch/Source/WebCore/platform/Logging.h	2017-10-20 12:45:46 UTC (rev 223757)
+++ branches/safari-604-branch/Source/WebCore/platform/Logging.h	2017-10-20 15:00:04 UTC (rev 223758)
@@ -42,6 +42,7 @@
     M(Archives) \
     M(Compositing) \
     M(ContentFiltering) \
+    M(DatabaseTracker) \
     M(DisplayLists) \
     M(DOMTimers) \
     M(Editing) \

Modified: branches/safari-604-branch/Tools/ChangeLog (223757 => 223758)


--- branches/safari-604-branch/Tools/ChangeLog	2017-10-20 12:45:46 UTC (rev 223757)
+++ branches/safari-604-branch/Tools/ChangeLog	2017-10-20 15:00:04 UTC (rev 223758)
@@ -1,5 +1,31 @@
 2017-10-19  Jason Marcell  <jmarc...@apple.com>
 
+        Cherry-pick r223427. rdar://problem/34745623
+
+    2017-10-16  Maureen Daum  <md...@apple.com>
+
+            If we fail to delete any database file, don't remove its information from the tracker database
+            <rdar://problem/34576132> and https://bugs.webkit.org/show_bug.cgi?id=178251
+
+            Reviewed by Brady Eidson.
+
+            Add tests that verify we correctly delete databases and remove their information from
+            the tracker database, even if the database doesn't exist. Verify that if we fail to
+            delete a database, we don't remove its information from the tracker database.
+
+            * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+            Move DatabaseTrackerTest.cpp to DatabaseTrackerTest.mm so that we can use the cocoa
+            method for creating a temporary directory in the tests.
+            * TestWebKitAPI/Tests/WebCore/DatabaseTrackerTest.cpp: Removed.
+            The existing test was copied to DatabaseTrackerTest.mm.
+            * TestWebKitAPI/Tests/WebCore/cocoa/DatabaseTrackerTest.mm: Added.
+            (TestWebKitAPI::TEST):
+            (TestWebKitAPI::addToDatabasesTable):
+            (TestWebKitAPI::removeDirectoryAndAllContents):
+            (TestWebKitAPI::createFileAtPath):
+
+2017-10-19  Jason Marcell  <jmarc...@apple.com>
+
         Cherry-pick r223565. rdar://problem/35041490
 
     2017-10-17  John Wilander  <wilan...@apple.com>

Modified: branches/safari-604-branch/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (223757 => 223758)


--- branches/safari-604-branch/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2017-10-20 12:45:46 UTC (rev 223757)
+++ branches/safari-604-branch/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2017-10-20 15:00:04 UTC (rev 223758)
@@ -231,7 +231,8 @@
 		6356FB221EC4E0BA0044BF18 /* VisibleContentRect.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6356FB211EC4E0BA0044BF18 /* VisibleContentRect.mm */; };
 		636353A71E98665D0009F8AF /* GeolocationGetCurrentPositionResult.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 636353A61E9861940009F8AF /* GeolocationGetCurrentPositionResult.html */; };
 		6BFD294C1D5E6C1D008EC968 /* HashCountedSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A38D7E51C752D5F004F157D /* HashCountedSet.cpp */; };
-		755A20AF1E6E38630093C69F /* DatabaseTrackerTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 755A20AE1E6E38630093C69F /* DatabaseTrackerTest.cpp */; };
+		751B05D61F8EAC410028A09E /* DatabaseTrackerTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 751B05D51F8EAC1A0028A09E /* DatabaseTrackerTest.mm */; };
+		754CEC811F6722F200D0039A /* AutoFillAvailable.mm in Sources */ = {isa = PBXBuildFile; fileRef = 754CEC801F6722DC00D0039A /* AutoFillAvailable.mm */; };
 		764322D71B61CCC30024F801 /* WordBoundaryTypingAttributes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 764322D51B61CCA40024F801 /* WordBoundaryTypingAttributes.mm */; };
 		7673499D1930C5BB00E44DF9 /* StopLoadingDuringDidFailProvisionalLoad_bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7673499A1930182E00E44DF9 /* StopLoadingDuringDidFailProvisionalLoad_bundle.cpp */; };
 		76E182DD1547569100F1FADD /* WillSendSubmitEvent_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 76E182DC1547569100F1FADD /* WillSendSubmitEvent_Bundle.cpp */; };
@@ -1283,7 +1284,8 @@
 		634910DF1E9D3FF300880309 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; };
 		6356FB211EC4E0BA0044BF18 /* VisibleContentRect.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = VisibleContentRect.mm; sourceTree = "<group>"; };
 		636353A61E9861940009F8AF /* GeolocationGetCurrentPositionResult.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = GeolocationGetCurrentPositionResult.html; sourceTree = "<group>"; };
-		755A20AE1E6E38630093C69F /* DatabaseTrackerTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DatabaseTrackerTest.cpp; sourceTree = "<group>"; };
+		751B05D51F8EAC1A0028A09E /* DatabaseTrackerTest.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = DatabaseTrackerTest.mm; sourceTree = "<group>"; };
+		754CEC801F6722DC00D0039A /* AutoFillAvailable.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = AutoFillAvailable.mm; sourceTree = "<group>"; };
 		7560917719259C59009EF06E /* MemoryCacheAddImageToCacheIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MemoryCacheAddImageToCacheIOS.mm; sourceTree = "<group>"; };
 		75F3133F18C171B70041CAEC /* EphemeralSessionPushStateNoHistoryCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EphemeralSessionPushStateNoHistoryCallback.cpp; sourceTree = "<group>"; };
 		764322D51B61CCA40024F801 /* WordBoundaryTypingAttributes.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WordBoundaryTypingAttributes.mm; sourceTree = "<group>"; };
@@ -1978,7 +1980,6 @@
 				1C9EB8401E380DA1005C6442 /* ComplexTextController.cpp */,
 				7CB184C41AA3F2100066EDFD /* ContentExtensions.cpp */,
 				CD5451E919E41F9D0016936F /* CSSParser.cpp */,
-				755A20AE1E6E38630093C69F /* DatabaseTrackerTest.cpp */,
 				260BA5781B1D2E7B004FA07C /* DFACombiner.cpp */,
 				260BA57A1B1D2EE2004FA07C /* DFAHelpers.h */,
 				26F6E1EF1ADC749B00DE696B /* DFAMinimizer.cpp */,
@@ -2706,6 +2707,7 @@
 		CD89D0371C4EDB1300040A04 /* cocoa */ = {
 			isa = PBXGroup;
 			children = (
+				751B05D51F8EAC1A0028A09E /* DatabaseTrackerTest.mm */,
 				5769C50A1D9B0001000847FB /* SerializedCryptoKeyWrap.mm */,
 				A17991861E1C994E00A505ED /* SharedBuffer.mm */,
 				93A7EB3C18FA63A4009E7670 /* URLExtras.mm */,
@@ -3042,7 +3044,6 @@
 				7CCE7F291A411B1000447C4C /* CustomProtocolsInvalidScheme.mm in Sources */,
 				7CCE7F2A1A411B1000447C4C /* CustomProtocolsSyncXHRTest.mm in Sources */,
 				7CCE7F2B1A411B1000447C4C /* CustomProtocolsTest.mm in Sources */,
-				755A20AF1E6E38630093C69F /* DatabaseTrackerTest.cpp in Sources */,
 				2DC4CF771D2D9DD800ECCC94 /* DataDetection.mm in Sources */,
 				F4D4F3B61E4E2BCB00BB2767 /* DataInteractionSimulator.mm in Sources */,
 				F4D4F3B91E4E36E400BB2767 /* DataInteractionTests.mm in Sources */,
@@ -3319,6 +3320,7 @@
 				7C417F331D19E14800B8EF53 /* WKWebViewDefaultNavigationDelegate.mm in Sources */,
 				0F3B94A71A77267400DE3272 /* WKWebViewEvaluateJavaScript.mm in Sources */,
 				D34E08761E4E42E1005FF14A /* WKWebViewGetContents.mm in Sources */,
+				751B05D61F8EAC410028A09E /* DatabaseTrackerTest.mm in Sources */,
 				315231CA1EB3B3C700A22A16 /* GPUCommandQueue.mm in Sources */,
 				F4FA91811E61849B007B8C1D /* WKWebViewSelectionTests.mm in Sources */,
 				0799C3491EBA2D7B003B7532 /* UserMediaDisabled.mm in Sources */,

Deleted: branches/safari-604-branch/Tools/TestWebKitAPI/Tests/WebCore/DatabaseTrackerTest.cpp (223757 => 223758)


--- branches/safari-604-branch/Tools/TestWebKitAPI/Tests/WebCore/DatabaseTrackerTest.cpp	2017-10-20 12:45:46 UTC (rev 223757)
+++ branches/safari-604-branch/Tools/TestWebKitAPI/Tests/WebCore/DatabaseTrackerTest.cpp	2017-10-20 15:00:04 UTC (rev 223758)
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#include "config.h"
-
-#if PLATFORM(IOS)
-
-#include <WebCore/DatabaseTracker.h>
-#include <WebCore/FileSystem.h>
-
-using namespace WebCore;
-
-namespace TestWebKitAPI {
-
-TEST(DatabaseTracker, DeleteDatabaseFileIfEmpty)
-{
-    PlatformFileHandle handle;
-    String databaseFilePath = openTemporaryFile("tempEmptyDatabase", handle);
-    closeFile(handle);
-
-    long long fileSize;
-    getFileSize(databaseFilePath, fileSize);
-    EXPECT_EQ(0, fileSize);
-
-    EXPECT_TRUE(DatabaseTracker::deleteDatabaseFileIfEmpty(databaseFilePath));
-
-    bool fileStillExists = fileExists(databaseFilePath);
-    EXPECT_FALSE(fileStillExists);
-
-    if (fileStillExists)
-        deleteFile(databaseFilePath);
-}
-
-} // namespace TestWebKitAPI
-
-#endif // PLATFORM(IOS)

Added: branches/safari-604-branch/Tools/TestWebKitAPI/Tests/WebCore/cocoa/DatabaseTrackerTest.mm (0 => 223758)


--- branches/safari-604-branch/Tools/TestWebKitAPI/Tests/WebCore/cocoa/DatabaseTrackerTest.mm	                        (rev 0)
+++ branches/safari-604-branch/Tools/TestWebKitAPI/Tests/WebCore/cocoa/DatabaseTrackerTest.mm	2017-10-20 15:00:04 UTC (rev 223758)
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#include "config.h"
+
+#include <WebCore/DatabaseTracker.h>
+#include <WebCore/FileSystem.h>
+#include <WebCore/OriginLock.h>
+#include <WebCore/SQLiteDatabase.h>
+#include <WebCore/SQLiteStatement.h>
+#include <WebCore/SecurityOriginData.h>
+
+using namespace WebCore;
+
+namespace TestWebKitAPI {
+
+#if PLATFORM(IOS)
+
+TEST(DatabaseTracker, DeleteDatabaseFileIfEmpty)
+{
+    PlatformFileHandle handle;
+    String databaseFilePath = openTemporaryFile("tempEmptyDatabase", handle);
+    closeFile(handle);
+
+    long long fileSize;
+    getFileSize(databaseFilePath, fileSize);
+    EXPECT_EQ(0, fileSize);
+
+    EXPECT_TRUE(DatabaseTracker::deleteDatabaseFileIfEmpty(databaseFilePath));
+
+    bool fileStillExists = fileExists(databaseFilePath);
+    EXPECT_FALSE(fileStillExists);
+
+    if (fileStillExists)
+        deleteFile(databaseFilePath);
+}
+
+#endif // PLATFORM(IOS)
+
+#if PLATFORM(COCOA)
+
+static void addToDatabasesTable(const String& databasePath, const SecurityOriginData& origin, const String& newDatabaseName, const String& newDatabasePath)
+{
+    SQLiteDatabase database;
+    database.open(databasePath);
+
+    SQLiteStatement addDatabaseStatement(database, "INSERT INTO Databases (origin, name, path) VALUES (?, ?, ?);");
+    addDatabaseStatement.prepare();
+    addDatabaseStatement.bindText(1, origin.databaseIdentifier());
+    addDatabaseStatement.bindText(2, newDatabaseName);
+    addDatabaseStatement.bindText(3, newDatabasePath);
+    addDatabaseStatement.executeCommand();
+
+    database.close();
+}
+
+static void removeDirectoryAndAllContents(const String& directoryPath)
+{
+    for (const auto& file : listDirectory(directoryPath, "*"))
+        EXPECT_TRUE(deleteFile(file));
+
+    if (fileExists(directoryPath))
+        EXPECT_TRUE(deleteEmptyDirectory(directoryPath));
+}
+
+static void createFileAtPath(const String& path)
+{
+    PlatformFileHandle fileHandle = openFile(path, OpenForWrite);
+    EXPECT_NE(-1, fileHandle);
+    closeFile(fileHandle);
+    EXPECT_TRUE(fileExists(path));
+}
+
+TEST(DatabaseTracker, DeleteOrigin)
+{
+    // Test the expected case. There is an entry in both the Origins and Databases
+    // tables, and an actual database on disk.
+    // In this case, we should remove the origin's information from both the Origins
+    // and Databases tables, and remove the database from disk.
+    NSString *webSQLDirectory = createTemporaryDirectory(@"WebSQL");
+    String databaseDirectoryPath(webSQLDirectory.UTF8String);
+
+    std::unique_ptr<DatabaseTracker> databaseTracker = DatabaseTracker::trackerWithDatabasePath(databaseDirectoryPath);
+    SecurityOriginData origin("https", "webkit.org", 443);
+
+    databaseTracker->setQuota(origin, 5242880);
+    EXPECT_EQ((unsigned)1, databaseTracker->origins().size());
+
+    String databasePath = pathByAppendingComponent(databaseDirectoryPath, "Databases.db");
+    EXPECT_TRUE(fileExists(databasePath));
+
+    String webDatabaseName = "database_name";
+    addToDatabasesTable(databasePath, origin, webDatabaseName, "database.db");
+    EXPECT_EQ((unsigned)1, databaseTracker->databaseNames(origin).size());
+
+    String originPath = pathByAppendingComponent(databaseDirectoryPath, origin.databaseIdentifier());
+    EXPECT_TRUE(makeAllDirectories(originPath));
+    EXPECT_TRUE(fileExists(originPath));
+
+    String fullWebDatabasePath = databaseTracker->fullPathForDatabase(origin, webDatabaseName, false);
+    createFileAtPath(fullWebDatabasePath);
+
+    EXPECT_TRUE(databaseTracker->deleteOrigin(origin));
+    EXPECT_TRUE(databaseTracker->origins().isEmpty());
+    EXPECT_TRUE(databaseTracker->databaseNames(origin).isEmpty());
+
+#if PLATFORM(IOS)
+    EXPECT_TRUE(DatabaseTracker::deleteDatabaseFileIfEmpty(fullWebDatabasePath));
+    EXPECT_TRUE(deleteEmptyDirectory(originPath));
+#else
+    EXPECT_FALSE(fileExists(fullWebDatabasePath));
+    EXPECT_FALSE(fileExists(originPath));
+#endif
+
+    removeDirectoryAndAllContents(databaseDirectoryPath);
+    EXPECT_FALSE(fileExists(databaseDirectoryPath));
+}
+
+TEST(DatabaseTracker, DeleteOriginWhenDatabaseDoesNotExist)
+{
+    // Test the case where there is an entry in both the Origins and Databases tables,
+    // but not an actual database on disk.
+    // The information should still be removed from the tables.
+    NSString *webSQLDirectory = createTemporaryDirectory(@"WebSQL");
+    String databaseDirectoryPath(webSQLDirectory.UTF8String);
+
+    std::unique_ptr<DatabaseTracker> databaseTracker = DatabaseTracker::trackerWithDatabasePath(databaseDirectoryPath);
+    SecurityOriginData origin("https", "webkit.org", 443);
+
+    databaseTracker->setQuota(origin, 5242880);
+    EXPECT_EQ((unsigned)1, databaseTracker->origins().size());
+
+    String databasePath = pathByAppendingComponent(databaseDirectoryPath, "Databases.db");
+    EXPECT_TRUE(fileExists(databasePath));
+
+    String webDatabaseName = "database_name";
+    addToDatabasesTable(databasePath, origin, webDatabaseName, "database.db");
+    EXPECT_EQ((unsigned)1, databaseTracker->databaseNames(origin).size());
+
+    String webDatabaseFullPath = databaseTracker->fullPathForDatabase(origin, webDatabaseName, false);
+    EXPECT_FALSE(fileExists(webDatabaseFullPath));
+
+    EXPECT_TRUE(databaseTracker->deleteOrigin(origin));
+
+    EXPECT_TRUE(databaseTracker->origins().isEmpty());
+    EXPECT_TRUE(databaseTracker->databaseNames(origin).isEmpty());
+
+    removeDirectoryAndAllContents(databaseDirectoryPath);
+    EXPECT_FALSE(fileExists(databaseDirectoryPath));
+}
+
+TEST(DatabaseTracker, DeleteOriginWhenDeletingADatabaseFails)
+{
+    // Test the case where there are entries in both the Databases and Origins tables.
+    // There are also databases on disk.
+    // When we call deleteOrigin(), deleting one of these databases fails.
+    // In this case, we shouldn't remove the information from either the Databases or
+    // Origins tables.
+    NSString *webSQLDirectory = createTemporaryDirectory(@"WebSQL");
+    String databaseDirectoryPath(webSQLDirectory.UTF8String);
+
+    std::unique_ptr<DatabaseTracker> databaseTracker = DatabaseTracker::trackerWithDatabasePath(databaseDirectoryPath);
+    SecurityOriginData origin("https", "webkit.org", 443);
+
+    databaseTracker->setQuota(origin, 5242880);
+    EXPECT_EQ((unsigned)1, databaseTracker->origins().size());
+
+    String databasePath = pathByAppendingComponent(databaseDirectoryPath, "Databases.db");
+    EXPECT_TRUE(fileExists(databasePath));
+
+    String webDatabaseName = "database_name";
+    addToDatabasesTable(databasePath, origin, webDatabaseName, "database.db");
+    EXPECT_EQ((unsigned)1, databaseTracker->databaseNames(origin).size());
+
+    String originPath = pathByAppendingComponent(databaseDirectoryPath, origin.databaseIdentifier());
+    EXPECT_TRUE(makeAllDirectories(originPath));
+    EXPECT_TRUE(fileExists(originPath));
+
+    String fullWebDatabasePath = databaseTracker->fullPathForDatabase(origin, webDatabaseName, false);
+    createFileAtPath(fullWebDatabasePath);
+
+    chmod(fullWebDatabasePath.utf8().data(), 555);
+
+#if !PLATFORM(IOS)
+    chflags(fullWebDatabasePath.utf8().data(), UF_IMMUTABLE);
+#endif
+
+    EXPECT_FALSE(databaseTracker->deleteOrigin(origin));
+
+    EXPECT_TRUE(fileExists(fullWebDatabasePath));
+    EXPECT_TRUE(fileExists(originPath));
+
+    EXPECT_EQ((unsigned)1, databaseTracker->origins().size());
+    EXPECT_EQ((unsigned)1, databaseTracker->databaseNames(origin).size());
+
+    chmod(fullWebDatabasePath.utf8().data(), 666);
+
+#if !PLATFORM(IOS)
+    chflags(fullWebDatabasePath.utf8().data(), 0);
+#endif
+
+    EXPECT_TRUE(deleteFile(fullWebDatabasePath));
+    EXPECT_TRUE(deleteEmptyDirectory(originPath));
+
+    removeDirectoryAndAllContents(databaseDirectoryPath);
+    EXPECT_FALSE(fileExists(databaseDirectoryPath));
+}
+
+TEST(DatabaseTracker, DeleteDatabase)
+{
+    // Test the expected case. There is an entry in the Databases table
+    // and a database on disk. After the deletion, the database should be deleted
+    // from disk, and the information should be gone from the Databases table.
+    NSString *webSQLDirectory = createTemporaryDirectory(@"WebSQL");
+    String databaseDirectoryPath(webSQLDirectory.UTF8String);
+
+    std::unique_ptr<DatabaseTracker> databaseTracker = DatabaseTracker::trackerWithDatabasePath(databaseDirectoryPath);
+    SecurityOriginData origin("https", "webkit.org", 443);
+
+    databaseTracker->setQuota(origin, 5242880);
+    EXPECT_EQ((unsigned)1, databaseTracker->origins().size());
+
+    String databasePath = pathByAppendingComponent(databaseDirectoryPath, "Databases.db");
+    EXPECT_TRUE(fileExists(databasePath));
+
+    String webDatabaseName = "database_name";
+    addToDatabasesTable(databasePath, origin, webDatabaseName, "database.db");
+    EXPECT_EQ((unsigned)1, databaseTracker->databaseNames(origin).size());
+
+    String originPath = pathByAppendingComponent(databaseDirectoryPath, origin.databaseIdentifier());
+    EXPECT_TRUE(makeAllDirectories(originPath));
+    EXPECT_TRUE(fileExists(originPath));
+
+    String fullWebDatabasePath = databaseTracker->fullPathForDatabase(origin, webDatabaseName, false);
+    createFileAtPath(fullWebDatabasePath);
+
+    EXPECT_TRUE(databaseTracker->deleteDatabase(origin, webDatabaseName));
+    EXPECT_TRUE(databaseTracker->databaseNames(origin).isEmpty());
+
+#if PLATFORM(IOS)
+    EXPECT_TRUE(DatabaseTracker::deleteDatabaseFileIfEmpty(fullWebDatabasePath));
+#else
+    EXPECT_FALSE(fileExists(fullWebDatabasePath));
+#endif
+
+    EXPECT_EQ((unsigned)1, databaseTracker->origins().size());
+    EXPECT_TRUE(deleteEmptyDirectory(originPath));
+    removeDirectoryAndAllContents(databaseDirectoryPath);
+    EXPECT_FALSE(fileExists(databaseDirectoryPath));
+}
+
+TEST(DatabaseTracker, DeleteDatabaseWhenDatabaseDoesNotExist)
+{
+    // Test the case where we try to delete a database that doesn't exist on disk.
+    // We should still remove the database information from the Databases table.
+    NSString *webSQLDirectory = createTemporaryDirectory(@"WebSQL");
+    String databaseDirectoryPath(webSQLDirectory.UTF8String);
+
+    std::unique_ptr<DatabaseTracker> databaseTracker = DatabaseTracker::trackerWithDatabasePath(databaseDirectoryPath);
+    SecurityOriginData origin("https", "webkit.org", 443);
+
+    databaseTracker->setQuota(origin, 5242880);
+    EXPECT_EQ((unsigned)1, databaseTracker->origins().size());
+
+    String databasePath = pathByAppendingComponent(databaseDirectoryPath, "Databases.db");
+    EXPECT_TRUE(fileExists(databasePath));
+
+    String webDatabaseName = "database_name";
+    addToDatabasesTable(databasePath, origin, webDatabaseName, "database.db");
+    EXPECT_EQ((unsigned)1, databaseTracker->databaseNames(origin).size());
+
+    String webDatabaseFullPath = databaseTracker->fullPathForDatabase(origin, webDatabaseName, false);
+    EXPECT_FALSE(fileExists(webDatabaseFullPath));
+
+    EXPECT_TRUE(databaseTracker->deleteDatabase(origin, webDatabaseName));
+    EXPECT_TRUE(databaseTracker->databaseNames(origin).isEmpty());
+
+    removeDirectoryAndAllContents(databaseDirectoryPath);
+    EXPECT_FALSE(fileExists(databaseDirectoryPath));
+}
+
+#endif // PLATFORM(COCOA)
+
+} // namespace TestWebKitAPI
+
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to