Modern IDB: Implement native IDBFactory.getAllDatabaseNames for WebInspector.
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 28 Apr 2016 01:16:28 +0000 (01:16 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 28 Apr 2016 01:16:28 +0000 (01:16 +0000)
https://bugs.webkit.org/show_bug.cgi?id=157072

Reviewed by Alex Christensen.

Source/WebCore:

No new tests (Covered by changes to existing test).

Implement a new "getAllDatabaseNames" call on IDBFactory.

It is not exposed to the DOM, and is meant solely for internal WebInspector use.

* Modules/indexeddb/DOMWindowIndexedDatabase.h: Export some stuff to WebCoreTestSupport

* Modules/indexeddb/IDBDatabase.cpp:
(WebCore::IDBDatabase::createObjectStore):

* Modules/indexeddb/IDBDatabaseIdentifier.cpp:
(WebCore::IDBDatabaseIdentifier::databaseDirectoryRelativeToRoot):
* Modules/indexeddb/IDBDatabaseIdentifier.h:

* Modules/indexeddb/IDBFactory.cpp:
(WebCore::IDBFactory::getAllDatabaseNames):
* Modules/indexeddb/IDBFactory.h:

* Modules/indexeddb/client/IDBConnectionProxy.cpp:
(WebCore::IDBClient::IDBConnectionProxy::getAllDatabaseNames):
* Modules/indexeddb/client/IDBConnectionProxy.h:

* Modules/indexeddb/client/IDBConnectionToServer.cpp:
(WebCore::IDBClient::IDBConnectionToServer::getAllDatabaseNames):
(WebCore::IDBClient::IDBConnectionToServer::didGetAllDatabaseNames):
* Modules/indexeddb/client/IDBConnectionToServer.h:
* Modules/indexeddb/client/IDBConnectionToServerDelegate.h:

* Modules/indexeddb/server/IDBConnectionToClient.cpp:
(WebCore::IDBServer::IDBConnectionToClient::didGetAllDatabaseNames):
* Modules/indexeddb/server/IDBConnectionToClient.h:
* Modules/indexeddb/server/IDBConnectionToClientDelegate.h:

* Modules/indexeddb/server/IDBServer.cpp:
(WebCore::IDBServer::IDBServer::getAllDatabaseNames):
(WebCore::IDBServer::IDBServer::performGetAllDatabaseNames): Do the actual work of getting
  the appropriate directory listing and converting the paths to database names.
(WebCore::IDBServer::IDBServer::didGetAllDatabaseNames):
* Modules/indexeddb/server/IDBServer.h:

* Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
(WebCore::IDBServer::SQLiteIDBBackingStore::databaseNameFromEncodedFilename): Helper for IDBServer.
* Modules/indexeddb/server/SQLiteIDBBackingStore.h:

* Modules/indexeddb/shared/InProcessIDBServer.cpp:
(WebCore::InProcessIDBServer::getAllDatabaseNames):
(WebCore::InProcessIDBServer::didGetAllDatabaseNames):
* Modules/indexeddb/shared/InProcessIDBServer.h:

* inspector/InspectorIndexedDBAgent.cpp:
(WebCore::InspectorIndexedDBAgent::requestDatabaseNames): Use the new IDBFactory API to
  asynchronously get the list of database names.

* platform/CrossThreadCopier.cpp:
(WebCore::SecurityOriginData>::copy):
(WebCore::Vector<String>>::copy):
* platform/CrossThreadCopier.h:

* platform/FileSystem.cpp:
(WebCore::decodeFromFilename): Perform the reverse of encodeForFilename.
* platform/FileSystem.h:

* platform/cf/FileSystemCF.cpp:
(WebCore::stringFromFileSystemRepresentation):

* platform/glib/FileSystemGlib.cpp:
(WebCore::stringFromFileSystemRepresentation):

* platform/posix/FileSystemPOSIX.cpp:
(WebCore::lastComponentOfPathIgnoringTrailingSlash): Utility for peeling off the last component
  of a multi-component path.
(WebCore::listDirectory): This was broken when returning filenames with UTF in them. Fix it.

* platform/mac/WebCoreNSURLExtras.mm: Move the static hex digit utility functions to WTF.
(WebCore::userVisibleString):
(WebCore::isUserVisibleURL):
(WebCore::isHexDigit): Deleted.
(WebCore::hexDigit): Deleted.
(WebCore::hexDigitValue): Deleted.

Source/WebKit2:

Handle the process hop for the new getAllDatabaseNames call.

* DatabaseProcess/IndexedDB/WebIDBConnectionToClient.cpp:
(WebKit::WebIDBConnectionToClient::didGetAllDatabaseNames):
(WebKit::WebIDBConnectionToClient::getAllDatabaseNames):
* DatabaseProcess/IndexedDB/WebIDBConnectionToClient.h:
* DatabaseProcess/IndexedDB/WebIDBConnectionToClient.messages.in:

* Shared/WebCrossThreadCopier.cpp:
(WebCore::SecurityOriginData>::copy): Deleted, as its in WebCore now.
* Shared/WebCrossThreadCopier.h:

* WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp:
(WebKit::WebIDBConnectionToServer::getAllDatabaseNames):
(WebKit::WebIDBConnectionToServer::didGetAllDatabaseNames):
* WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.h:
* WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.messages.in:

Source/WTF:

Moved these Hex Digit utilities from WebCore URL code (???),
and add a checked version of getting the hex digit value.

* wtf/HexNumber.h:
(WTF::isHexDigit):
(WTF::uncheckedHexDigit):
(WTF::hexDigitValue):
(WTF::uncheckedHexDigitValue):

LayoutTests:

Add more to this test and re-enable it.

* TestExpectations:
* inspector/indexeddb/requestDatabaseNames-expected.txt:
* inspector/indexeddb/requestDatabaseNames.html:

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

45 files changed:
LayoutTests/ChangeLog
LayoutTests/TestExpectations
LayoutTests/inspector/indexeddb/requestDatabaseNames-expected.txt
LayoutTests/inspector/indexeddb/requestDatabaseNames.html
Source/WTF/ChangeLog
Source/WTF/wtf/HexNumber.h
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/DOMWindowIndexedDatabase.h
Source/WebCore/Modules/indexeddb/IDBDatabase.cpp
Source/WebCore/Modules/indexeddb/IDBDatabaseIdentifier.cpp
Source/WebCore/Modules/indexeddb/IDBDatabaseIdentifier.h
Source/WebCore/Modules/indexeddb/IDBFactory.cpp
Source/WebCore/Modules/indexeddb/IDBFactory.h
Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.cpp
Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.h
Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.cpp
Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.h
Source/WebCore/Modules/indexeddb/client/IDBConnectionToServerDelegate.h
Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.cpp
Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.h
Source/WebCore/Modules/indexeddb/server/IDBConnectionToClientDelegate.h
Source/WebCore/Modules/indexeddb/server/IDBServer.cpp
Source/WebCore/Modules/indexeddb/server/IDBServer.h
Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp
Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h
Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.cpp
Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.h
Source/WebCore/inspector/InspectorIndexedDBAgent.cpp
Source/WebCore/platform/CrossThreadCopier.cpp
Source/WebCore/platform/CrossThreadCopier.h
Source/WebCore/platform/FileSystem.cpp
Source/WebCore/platform/FileSystem.h
Source/WebCore/platform/cf/FileSystemCF.cpp
Source/WebCore/platform/glib/FileSystemGlib.cpp
Source/WebCore/platform/mac/WebCoreNSURLExtras.mm
Source/WebCore/platform/posix/FileSystemPOSIX.cpp
Source/WebKit2/ChangeLog
Source/WebKit2/DatabaseProcess/IndexedDB/WebIDBConnectionToClient.cpp
Source/WebKit2/DatabaseProcess/IndexedDB/WebIDBConnectionToClient.h
Source/WebKit2/DatabaseProcess/IndexedDB/WebIDBConnectionToClient.messages.in
Source/WebKit2/Shared/WebCrossThreadCopier.cpp
Source/WebKit2/Shared/WebCrossThreadCopier.h
Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp
Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.h
Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.messages.in

index c302710..5827682 100644 (file)
@@ -1,3 +1,16 @@
+2016-04-27  Brady Eidson  <beidson@apple.com>
+
+        Modern IDB: Implement native IDBFactory.getAllDatabaseNames for WebInspector.
+        https://bugs.webkit.org/show_bug.cgi?id=157072
+
+        Reviewed by Alex Christensen.
+
+        Add more to this test and re-enable it.
+
+        * TestExpectations:
+        * inspector/indexeddb/requestDatabaseNames-expected.txt:
+        * inspector/indexeddb/requestDatabaseNames.html:
+
 2016-04-27  Simon Fraser  <simon.fraser@apple.com>
 
         Test gardening; update results of tests that are marked as flakey.
index 8547c71..460bc16 100644 (file)
@@ -926,9 +926,6 @@ storage/indexeddb/modern/transaction-scheduler-5.html [ Skip ]
 storage/indexeddb/modern/transaction-scheduler-6.html [ Skip ]
 storage/indexeddb/transaction-coordination-within-database.html [ Skip ]
 
-# Inspector doesn't support modern IDB yet
-webkit.org/b/154686 inspector/indexeddb/requestDatabaseNames.html [ Skip ]
-
 # These two IDB tests are, by their nature, very slow
 # Skip these until we have a fix for webkit.org/b/155041
 storage/indexeddb/modern/exceed-open-file-limit.html [ Skip ]
index 8b27b19..6e21cf7 100644 (file)
@@ -1,5 +1,7 @@
 CONSOLE MESSAGE: line 10: Created Database 'Database1'
 CONSOLE MESSAGE: line 10: Created Database 'Database2'
+CONSOLE MESSAGE: line 10: Created Database 'ቍ'
+CONSOLE MESSAGE: line 10: Created Database '𐍆'
 
 PASS: No IndexedDB databases should exist initially
 Created Database 'Database1'
@@ -8,4 +10,10 @@ PASS: A single IndexedDB database should exist
 Created Database 'Database2'
 PASS: Two IndexedDB databases should exist
 ["Database1","Database2"]
+Created Database 'ቍ'
+PASS: Two IndexedDB databases should exist
+["Database1","Database2","ቍ"]
+Created Database '𐍆'
+PASS: Four IndexedDB databases should exist
+["Database1","Database2","ቍ","𐍆"]
 
index 17afe4a..e2d9755 100644 (file)
@@ -55,6 +55,29 @@ function test()
                     InspectorTest.expectNoError(error);
                     InspectorTest.expectThat(names.length === 2, "Two IndexedDB databases should exist");
                     InspectorTest.log(JSON.stringify(names));
+                    InspectorTest.evaluateInPage("createDatabase('\u124d')");
+                });
+            }
+        },
+        {
+            action: function() {
+                IndexedDBAgent.requestDatabaseNames(WebInspector.frameResourceManager.mainFrame.securityOrigin, function(error, names) {
+                    InspectorTest.expectNoError(error);
+                    InspectorTest.expectThat(names.length === 3, "Two IndexedDB databases should exist");
+                    InspectorTest.log(JSON.stringify(names));
+                    InspectorTest.evaluateInPage("createDatabase('\ud800\udf46')");
+                });
+            }
+        },
+        {
+            action: function() {
+                IndexedDBAgent.requestDatabaseNames(WebInspector.frameResourceManager.mainFrame.securityOrigin, function(error, names) {
+                    for (n in names)
+                        alert(names.n);
+
+                    InspectorTest.expectNoError(error);
+                    InspectorTest.expectThat(names.length === 4, "Four IndexedDB databases should exist");
+                    InspectorTest.log(JSON.stringify(names));
                     next();
                 });
             }
index 8b72ff7..cdcf0ad 100644 (file)
@@ -1,3 +1,19 @@
+2016-04-27  Brady Eidson  <beidson@apple.com>
+
+        Modern IDB: Implement native IDBFactory.getAllDatabaseNames for WebInspector.
+        https://bugs.webkit.org/show_bug.cgi?id=157072
+
+        Reviewed by Alex Christensen.
+
+        Moved these Hex Digit utilities from WebCore URL code (???), 
+        and add a checked version of getting the hex digit value.
+        
+        * wtf/HexNumber.h:
+        (WTF::isHexDigit):
+        (WTF::uncheckedHexDigit):
+        (WTF::hexDigitValue):
+        (WTF::uncheckedHexDigitValue):
+
 2016-04-25  Ryosuke Niwa  <rniwa@webkit.org>
 
         Remove the build flag for template elements
index 741a8c1..c43b5e4 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2011 Research In Motion Limited. All rights reserved.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -17,8 +18,7 @@
  * Boston, MA 02110-1301, USA.
  */
 
-#ifndef HexNumber_h
-#define HexNumber_h
+#pragma once
 
 #include <wtf/text/StringConcatenate.h>
 
@@ -111,6 +111,54 @@ inline void appendUnsignedAsHexFixedSize(unsigned number, T& destination, unsign
     destination.append(result.data(), result.size());
 }
 
+
+inline bool isHexDigit(char c)
+{
+    return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
+}
+
+inline char uncheckedHexDigit(int i)
+{
+    if (i < 0 || i > 16)
+        return '0';
+
+    return (i >= 10) ? i - 10 + 'A' : i + '0';
+}
+
+inline bool hexDigitValue(char c, char& result)
+{
+    if (c >= '0' && c <= '9') {
+        result = c - '0';
+        return true;
+    }
+
+    if (c >= 'A' && c <= 'F') {
+        result = c - 'A' + 10;
+        return true;
+    }
+
+    if (c >= 'a' && c <= 'f') {
+        result = c - 'a' + 10;
+        return true;
+    }
+
+    return false;
+}
+
+inline int uncheckedHexDigitValue(char c)
+{
+    if (c >= '0' && c <= '9')
+        return c - '0';
+
+    if (c >= 'A' && c <= 'F')
+        return c - 'A' + 10;
+
+    if (c >= 'a' && c <= 'f')
+        return c - 'a' + 10;
+
+    return 0;
+}
+
 } // namespace WTF
 
 using WTF::appendByteAsHex;
@@ -119,5 +167,7 @@ using WTF::appendUnsignedAsHexFixedSize;
 using WTF::placeByteAsHex;
 using WTF::placeByteAsHexCompressIfPossible;
 using WTF::Lowercase;
-
-#endif // HexNumber_h
+using WTF::isHexDigit;
+using WTF::uncheckedHexDigit;
+using WTF::hexDigitValue;
+using WTF::uncheckedHexDigitValue;
index f3f5d68..91f3cbe 100644 (file)
@@ -1,3 +1,92 @@
+2016-04-27  Brady Eidson  <beidson@apple.com>
+
+        Modern IDB: Implement native IDBFactory.getAllDatabaseNames for WebInspector.
+        https://bugs.webkit.org/show_bug.cgi?id=157072
+
+        Reviewed by Alex Christensen.
+
+        No new tests (Covered by changes to existing test).
+
+        Implement a new "getAllDatabaseNames" call on IDBFactory.
+        
+        It is not exposed to the DOM, and is meant solely for internal WebInspector use.
+
+        * Modules/indexeddb/DOMWindowIndexedDatabase.h: Export some stuff to WebCoreTestSupport
+
+        * Modules/indexeddb/IDBDatabase.cpp:
+        (WebCore::IDBDatabase::createObjectStore):
+
+        * Modules/indexeddb/IDBDatabaseIdentifier.cpp:
+        (WebCore::IDBDatabaseIdentifier::databaseDirectoryRelativeToRoot):
+        * Modules/indexeddb/IDBDatabaseIdentifier.h:
+
+        * Modules/indexeddb/IDBFactory.cpp:
+        (WebCore::IDBFactory::getAllDatabaseNames):
+        * Modules/indexeddb/IDBFactory.h:
+
+        * Modules/indexeddb/client/IDBConnectionProxy.cpp:
+        (WebCore::IDBClient::IDBConnectionProxy::getAllDatabaseNames):
+        * Modules/indexeddb/client/IDBConnectionProxy.h:
+
+        * Modules/indexeddb/client/IDBConnectionToServer.cpp:
+        (WebCore::IDBClient::IDBConnectionToServer::getAllDatabaseNames):
+        (WebCore::IDBClient::IDBConnectionToServer::didGetAllDatabaseNames):
+        * Modules/indexeddb/client/IDBConnectionToServer.h:
+        * Modules/indexeddb/client/IDBConnectionToServerDelegate.h:
+
+        * Modules/indexeddb/server/IDBConnectionToClient.cpp:
+        (WebCore::IDBServer::IDBConnectionToClient::didGetAllDatabaseNames):
+        * Modules/indexeddb/server/IDBConnectionToClient.h:
+        * Modules/indexeddb/server/IDBConnectionToClientDelegate.h:
+
+        * Modules/indexeddb/server/IDBServer.cpp:
+        (WebCore::IDBServer::IDBServer::getAllDatabaseNames):
+        (WebCore::IDBServer::IDBServer::performGetAllDatabaseNames): Do the actual work of getting 
+          the appropriate directory listing and converting the paths to database names.
+        (WebCore::IDBServer::IDBServer::didGetAllDatabaseNames):
+        * Modules/indexeddb/server/IDBServer.h:
+
+        * Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
+        (WebCore::IDBServer::SQLiteIDBBackingStore::databaseNameFromEncodedFilename): Helper for IDBServer.
+        * Modules/indexeddb/server/SQLiteIDBBackingStore.h:
+
+        * Modules/indexeddb/shared/InProcessIDBServer.cpp:
+        (WebCore::InProcessIDBServer::getAllDatabaseNames):
+        (WebCore::InProcessIDBServer::didGetAllDatabaseNames):
+        * Modules/indexeddb/shared/InProcessIDBServer.h:
+
+        * inspector/InspectorIndexedDBAgent.cpp:
+        (WebCore::InspectorIndexedDBAgent::requestDatabaseNames): Use the new IDBFactory API to
+          asynchronously get the list of database names.
+
+        * platform/CrossThreadCopier.cpp:
+        (WebCore::SecurityOriginData>::copy):
+        (WebCore::Vector<String>>::copy):
+        * platform/CrossThreadCopier.h:
+
+        * platform/FileSystem.cpp:
+        (WebCore::decodeFromFilename): Perform the reverse of encodeForFilename.
+        * platform/FileSystem.h:
+
+        * platform/cf/FileSystemCF.cpp:
+        (WebCore::stringFromFileSystemRepresentation):
+
+        * platform/glib/FileSystemGlib.cpp:
+        (WebCore::stringFromFileSystemRepresentation):
+        
+        * platform/posix/FileSystemPOSIX.cpp:
+        (WebCore::lastComponentOfPathIgnoringTrailingSlash): Utility for peeling off the last component
+          of a multi-component path.
+        (WebCore::listDirectory): This was broken when returning filenames with UTF in them. Fix it.
+        
+        * platform/mac/WebCoreNSURLExtras.mm: Move the static hex digit utility functions to WTF.
+        (WebCore::userVisibleString):
+        (WebCore::isUserVisibleURL):
+        (WebCore::isHexDigit): Deleted.
+        (WebCore::hexDigit): Deleted.
+        (WebCore::hexDigitValue): Deleted.
+    
+
 2016-04-27  Enrica Casucci  <enrica@apple.com>
 
         Refactor findExplodedTextNodeAtPoint to move core functionality in RenderBlockFlow.
index 073b593..0c6e830 100644 (file)
@@ -44,7 +44,7 @@ public:
 
     static DOMWindowIndexedDatabase* from(DOMWindow*);
 
-    static IDBFactory* indexedDB(DOMWindow&);
+    WEBCORE_EXPORT static IDBFactory* indexedDB(DOMWindow&);
 
     void disconnectFrameForDocumentSuspension() override;
     void reconnectFrameFromDocumentSuspension(Frame*) override;
index 0f05b98..12d0c61 100644 (file)
@@ -97,7 +97,7 @@ RefPtr<WebCore::IDBObjectStore> IDBDatabase::createObjectStore(const String&, co
 
 RefPtr<WebCore::IDBObjectStore> IDBDatabase::createObjectStore(const String& name, const IDBKeyPath& keyPath, bool autoIncrement, ExceptionCodeWithMessage& ec)
 {
-    LOG(IndexedDB, "IDBDatabase::createObjectStore");
+    LOG(IndexedDB, "IDBDatabase::createObjectStore - (%s %s)", m_info.name().utf8().data(), name.utf8().data());
 
     ASSERT(!m_versionChangeTransaction || m_versionChangeTransaction->isVersionChange());
 
index c94d96f..8cd62f2 100644 (file)
@@ -59,13 +59,18 @@ IDBDatabaseIdentifier IDBDatabaseIdentifier::isolatedCopy() const
 
 String IDBDatabaseIdentifier::databaseDirectoryRelativeToRoot(const String& rootDirectory) const
 {
-    String mainFrameDirectory = pathByAppendingComponent(rootDirectory, m_mainFrameOrigin.securityOrigin()->databaseIdentifier());
+    return databaseDirectoryRelativeToRoot(m_mainFrameOrigin, m_openingOrigin, rootDirectory);
+}
+
+String IDBDatabaseIdentifier::databaseDirectoryRelativeToRoot(const SecurityOriginData& topLevelOrigin, const SecurityOriginData& openingOrigin, const String& rootDirectory)
+{
+    String mainFrameDirectory = pathByAppendingComponent(rootDirectory, topLevelOrigin.securityOrigin()->databaseIdentifier());
 
     // If the opening origin and main frame origins are the same, there is no partitioning.
-    if (m_openingOrigin == m_mainFrameOrigin)
+    if (openingOrigin == topLevelOrigin)
         return mainFrameDirectory;
 
-    return pathByAppendingComponent(mainFrameDirectory, m_openingOrigin.securityOrigin()->databaseIdentifier());
+    return pathByAppendingComponent(mainFrameDirectory, openingOrigin.securityOrigin()->databaseIdentifier());
 }
 
 #ifndef NDEBUG
index f9ef010..31e41aa 100644 (file)
@@ -93,6 +93,7 @@ public:
     const String& databaseName() const { return m_databaseName; }
 
     String databaseDirectoryRelativeToRoot(const String& rootDirectory) const;
+    static String databaseDirectoryRelativeToRoot(const SecurityOriginData& topLevelOrigin, const SecurityOriginData& openingOrigin, const String& rootDirectory);
 
     template<class Encoder> void encode(Encoder&) const;
     template<class Decoder> static bool decode(Decoder&, IDBDatabaseIdentifier&);
index 9d0a77a..be8f9b4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015, 2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -159,6 +159,11 @@ short IDBFactory::cmp(ScriptExecutionContext& context, JSValue firstValue, JSVal
     return first->compare(second.get());
 }
 
+void IDBFactory::getAllDatabaseNames(const SecurityOrigin& mainFrameOrigin, const SecurityOrigin& openingOrigin, std::function<void (const Vector<String>&)> callback)
+{
+    m_connectionProxy->getAllDatabaseNames(mainFrameOrigin, openingOrigin, callback);
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(INDEXED_DATABASE)
index 1fdf713..8386271 100644 (file)
 
 #if ENABLE(INDEXED_DATABASE)
 
+#include <functional>
 #include <wtf/Forward.h>
 #include <wtf/Ref.h>
 #include <wtf/ThreadSafeRefCounted.h>
+#include <wtf/Vector.h>
 
 namespace JSC {
 class JSValue;
@@ -39,6 +41,7 @@ namespace WebCore {
 
 class IDBOpenDBRequest;
 class ScriptExecutionContext;
+class SecurityOrigin;
 
 struct ExceptionCodeWithMessage;
 
@@ -58,6 +61,8 @@ public:
 
     short cmp(ScriptExecutionContext&, JSC::JSValue first, JSC::JSValue second, ExceptionCodeWithMessage&);
 
+    WEBCORE_EXPORT void getAllDatabaseNames(const SecurityOrigin& mainFrameOrigin, const SecurityOrigin& openingOrigin, std::function<void (const Vector<String>&)>);
+
 private:
     explicit IDBFactory(IDBClient::IDBConnectionProxy&);
 
index 91d5755..9574b7f 100644 (file)
@@ -82,6 +82,15 @@ RefPtr<IDBOpenDBRequest> IDBConnectionProxy::deleteDatabase(ScriptExecutionConte
     return WTFMove(request);
 }
 
+void IDBConnectionProxy::getAllDatabaseNames(const SecurityOrigin& mainFrameOrigin, const SecurityOrigin& openingOrigin, std::function<void (const Vector<String>&)> callback)
+{
+    // This method is only meant to be called by the web inspector on the main thread.
+    RELEASE_ASSERT(isMainThread());
+
+    m_connectionToServer.getAllDatabaseNames(mainFrameOrigin, openingOrigin, callback);
+}
+
+
 } // namesapce IDBClient
 } // namespace WebCore
 
index ef5bb77..d2ccd0e 100644 (file)
 #if ENABLE(INDEXED_DATABASE)
 
 #include "IDBConnectionToServer.h"
+#include <functional>
 #include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
 
 namespace WebCore {
 
 class IDBDatabaseIdentifier;
 class IDBOpenDBRequest;
 class ScriptExecutionContext;
+class SecurityOrigin;
 
 namespace IDBClient {
 
@@ -57,6 +61,8 @@ public:
     void ref();
     void deref();
 
+    void getAllDatabaseNames(const SecurityOrigin& mainFrameOrigin, const SecurityOrigin& openingOrigin, std::function<void (const Vector<String>&)>);
+
 private:
     IDBConnectionToServer& m_connectionToServer;
     uint64_t m_serverConnectionIdentifier;
index d0a1b2f..0bd9068 100644 (file)
@@ -411,6 +411,23 @@ bool IDBConnectionToServer::hasRecordOfTransaction(const IDBTransaction& transac
     return m_pendingTransactions.contains(identifier) || m_committingTransactions.contains(identifier) || m_abortingTransactions.contains(identifier);
 }
 
+void IDBConnectionToServer::getAllDatabaseNames(const SecurityOrigin& mainFrameOrigin, const SecurityOrigin& openingOrigin, std::function<void (const Vector<String>&)> callback)
+{
+    static uint64_t callbackID = 0;
+
+    m_getAllDatabaseNamesCallbacks.add(++callbackID, WTFMove(callback));
+
+    m_delegate->getAllDatabaseNames(SecurityOriginData::fromSecurityOrigin(mainFrameOrigin), SecurityOriginData::fromSecurityOrigin(openingOrigin), callbackID);
+}
+
+void IDBConnectionToServer::didGetAllDatabaseNames(uint64_t callbackID, const Vector<String>& databaseNames)
+{
+    auto callback = m_getAllDatabaseNamesCallbacks.take(callbackID);
+    ASSERT(callback);
+
+    callback(databaseNames);
+}
+
 } // namespace IDBClient
 } // namespace WebCore
 
index b01441c..3ccb32c 100644 (file)
@@ -123,6 +123,9 @@ public:
     void registerDatabaseConnection(IDBDatabase&);
     void unregisterDatabaseConnection(IDBDatabase&);
 
+    void getAllDatabaseNames(const SecurityOrigin& mainFrameOrigin, const SecurityOrigin& openingOrigin, std::function<void (const Vector<String>&)>);
+    WEBCORE_EXPORT void didGetAllDatabaseNames(uint64_t callbackID, const Vector<String>& databaseNames);
+
 private:
     IDBConnectionToServer(IDBConnectionToServerDelegate&);
 
@@ -140,6 +143,8 @@ private:
     HashMap<IDBResourceIdentifier, RefPtr<IDBTransaction>> m_abortingTransactions;
     HashMap<IDBResourceIdentifier, RefPtr<TransactionOperation>> m_activeOperations;
 
+    HashMap<uint64_t, std::function<void (const Vector<String>&)>> m_getAllDatabaseNamesCallbacks;
+
     std::unique_ptr<IDBConnectionProxy> m_proxy;
 };
 
index 370b3ba..d8031c8 100644 (file)
@@ -42,6 +42,8 @@ class IDBResourceIdentifier;
 class IDBTransactionInfo;
 class IDBValue;
 
+struct SecurityOriginData;
+
 namespace IndexedDB {
 enum class ObjectStoreOverwriteMode;
 }
@@ -77,6 +79,8 @@ public:
     virtual void abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier) = 0;
     virtual void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier) = 0;
 
+    virtual void getAllDatabaseNames(const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID) = 0;
+
     virtual void ref() = 0;
     virtual void deref() = 0;
 };
index b952f8c..4bf41e0 100644 (file)
@@ -138,6 +138,11 @@ void IDBConnectionToClient::notifyOpenDBRequestBlocked(const IDBResourceIdentifi
     m_delegate->notifyOpenDBRequestBlocked(requestIdentifier, oldVersion, newVersion);
 }
 
+void IDBConnectionToClient::didGetAllDatabaseNames(uint64_t callbackID, const Vector<String>& databaseNames)
+{
+    m_delegate->didGetAllDatabaseNames(callbackID, databaseNames);
+}
+
 } // namespace IDBServer
 } // namespace WebCore
 
index c5dc42c..7e24647 100644 (file)
@@ -69,6 +69,8 @@ public:
 
     void notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion);
 
+    void didGetAllDatabaseNames(uint64_t callbackID, const Vector<String>& databaseNames);
+
 private:
     IDBConnectionToClient(IDBConnectionToClientDelegate&);
     
index c423e4c..42c54ab 100644 (file)
@@ -28,6 +28,9 @@
 
 #if ENABLE(INDEXED_DATABASE)
 
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
+
 namespace WebCore {
 
 class IDBError;
@@ -64,6 +67,8 @@ public:
     virtual void didStartTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&) = 0;
     virtual void notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion) = 0;
 
+    virtual void didGetAllDatabaseNames(uint64_t callbackID, const Vector<String>& databaseNames) = 0;
+
     virtual void ref() = 0;
     virtual void deref() = 0;
 };
index d1898e1..0833857 100644 (file)
@@ -28,6 +28,7 @@
 
 #if ENABLE(INDEXED_DATABASE)
 
+#include "CrossThreadCopier.h"
 #include "IDBRequestData.h"
 #include "IDBResultData.h"
 #include "Logging.h"
@@ -376,6 +377,35 @@ void IDBServer::didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier,
         databaseConnection->didFireVersionChangeEvent(requestIdentifier);
 }
 
+void IDBServer::getAllDatabaseNames(uint64_t serverConnectionIdentifier, const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID)
+{
+    postDatabaseTask(createCrossThreadTask(*this, &IDBServer::performGetAllDatabaseNames, serverConnectionIdentifier, mainFrameOrigin, openingOrigin, callbackID));
+}
+
+void IDBServer::performGetAllDatabaseNames(uint64_t serverConnectionIdentifier, const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID)
+{
+    String directory = IDBDatabaseIdentifier::databaseDirectoryRelativeToRoot(mainFrameOrigin, openingOrigin, m_databaseDirectoryPath);
+
+    Vector<String> entries = listDirectory(directory, ASCIILiteral("*"));
+    Vector<String> databases;
+    databases.reserveInitialCapacity(entries.size());
+    for (auto& entry : entries) {
+        String encodedName = lastComponentOfPathIgnoringTrailingSlash(entry);
+        databases.uncheckedAppend(SQLiteIDBBackingStore::databaseNameFromEncodedFilename(encodedName));
+    }
+
+    postDatabaseTaskReply(createCrossThreadTask(*this, &IDBServer::didGetAllDatabaseNames, serverConnectionIdentifier, callbackID, databases));
+}
+
+void IDBServer::didGetAllDatabaseNames(uint64_t serverConnectionIdentifier, uint64_t callbackID, const Vector<String>& databaseNames)
+{
+    auto connection = m_connectionMap.get(serverConnectionIdentifier);
+    if (!connection)
+        return;
+
+    connection->didGetAllDatabaseNames(callbackID, databaseNames);
+}
+
 void IDBServer::postDatabaseTask(std::unique_ptr<CrossThreadTask>&& task)
 {
     ASSERT(isMainThread());
index 65a02c2..b06917a 100644 (file)
@@ -82,6 +82,8 @@ public:
     WEBCORE_EXPORT void abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier);
     WEBCORE_EXPORT void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier);
 
+    WEBCORE_EXPORT void getAllDatabaseNames(uint64_t serverConnectionIdentifier, const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID);
+
     void postDatabaseTask(std::unique_ptr<CrossThreadTask>&&);
     void postDatabaseTaskReply(std::unique_ptr<CrossThreadTask>&&);
 
@@ -100,6 +102,9 @@ private:
 
     UniqueIDBDatabase& getOrCreateUniqueIDBDatabase(const IDBDatabaseIdentifier&);
 
+    void performGetAllDatabaseNames(uint64_t serverConnectionIdentifier, const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID);
+    void didGetAllDatabaseNames(uint64_t serverConnectionIdentifier, uint64_t callbackID, const Vector<String>& databaseNames);
+
     static void databaseThreadEntry(void*);
     void databaseRunLoop();
     void handleTaskRepliesOnMainThread();
index c161efe..23d9363 100644 (file)
@@ -659,6 +659,17 @@ std::unique_ptr<IDBDatabaseInfo> SQLiteIDBBackingStore::extractExistingDatabaseI
     return databaseInfo;
 }
 
+String SQLiteIDBBackingStore::databaseNameFromEncodedFilename(const String& encodedName)
+{
+    if (equal(encodedName, ASCIILiteral("%00")))
+        return { };
+
+    String partiallyDecoded = encodedName;
+    partiallyDecoded.replace(ASCIILiteral("%2E"), ASCIILiteral("."));
+
+    return decodeFromFilename(partiallyDecoded);
+}
+
 String SQLiteIDBBackingStore::filenameForDatabaseName() const
 {
     ASSERT(!m_identifier.databaseName().isNull());
index 35d4979..f99f885 100644 (file)
@@ -87,6 +87,8 @@ public:
 
     IDBError getBlobRecordsForObjectStoreRecord(int64_t objectStoreRecord, Vector<String>& blobURLs, Vector<String>& blobFilePaths);
 
+    static String databaseNameFromEncodedFilename(const String&);
+
 private:
     String filenameForDatabaseName() const;
     String fullDatabasePath() const;
index 5dc83eb..31dfaa6 100644 (file)
@@ -401,6 +401,22 @@ void InProcessIDBServer::didFireVersionChangeEvent(uint64_t databaseConnectionId
     });
 }
 
+void InProcessIDBServer::getAllDatabaseNames(const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID)
+{
+    RefPtr<InProcessIDBServer> protector(this);
+    RunLoop::current().dispatch([this, protector, mainFrameOrigin, openingOrigin, callbackID] {
+        m_server->getAllDatabaseNames(m_connectionToServer->identifier(), mainFrameOrigin, openingOrigin, callbackID);
+    });
+}
+
+void InProcessIDBServer::didGetAllDatabaseNames(uint64_t callbackID, const Vector<String>& databaseNames)
+{
+    RefPtr<InProcessIDBServer> protector(this);
+    RunLoop::current().dispatch([this, protector, callbackID, databaseNames] {
+        m_connectionToServer->didGetAllDatabaseNames(callbackID, databaseNames);
+    });
+}
+
 void InProcessIDBServer::accessToTemporaryFileComplete(const String& path)
 {
     deleteFile(path);
index fe284c2..d047def 100644 (file)
@@ -75,6 +75,7 @@ public:
     void databaseConnectionClosed(uint64_t databaseConnectionIdentifier) final;
     void abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier) final;
     void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier) final;
+    void getAllDatabaseNames(const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID) final;
 
     // IDBConnectionToClient
     uint64_t identifier() const override;
@@ -96,6 +97,7 @@ public:
     void fireVersionChangeEvent(IDBServer::UniqueIDBDatabaseConnection&, const IDBResourceIdentifier& requestIdentifier, uint64_t requestedVersion) final;
     void didStartTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&) final;
     void notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion) final;
+    void didGetAllDatabaseNames(uint64_t callbackID, const Vector<String>& databaseNames) final;
 
     void ref() override { RefCounted<InProcessIDBServer>::ref(); }
     void deref() override { RefCounted<InProcessIDBServer>::deref(); }
index 70601fd..569327a 100644 (file)
@@ -90,62 +90,6 @@ namespace WebCore {
 
 namespace {
 
-#if 0 // IDBFactory::getDatabaseNames isn't implemented any more. Disable this for now.
-
-class GetDatabaseNamesCallback : public EventListener {
-    WTF_MAKE_NONCOPYABLE(GetDatabaseNamesCallback);
-public:
-    static Ref<GetDatabaseNamesCallback> create(Ref<RequestDatabaseNamesCallback>&& requestCallback, const String& securityOrigin)
-    {
-        return adoptRef(*new GetDatabaseNamesCallback(WTFMove(requestCallback), securityOrigin));
-    }
-
-    virtual ~GetDatabaseNamesCallback() { }
-
-    bool operator==(const EventListener& other) override
-    {
-        return this == &other;
-    }
-
-    void handleEvent(ScriptExecutionContext*, Event* event) override
-    {
-        if (!m_requestCallback->isActive())
-            return;
-        if (event->type() != eventNames().successEvent) {
-            m_requestCallback->sendFailure("Unexpected event type.");
-            return;
-        }
-
-        IDBRequest* idbRequest = static_cast<IDBRequest*>(event->target());
-        ExceptionCodeWithMessage ec;
-        RefPtr<IDBAny> requestResult = idbRequest->result(ec);
-        if (ec.code) {
-            m_requestCallback->sendFailure("Could not get result in callback.");
-            return;
-        }
-        if (requestResult->type() != IDBAny::Type::DOMStringList) {
-            m_requestCallback->sendFailure("Unexpected result type.");
-            return;
-        }
-
-        RefPtr<DOMStringList> databaseNamesList = requestResult->domStringList();
-        Ref<Inspector::Protocol::Array<String>> databaseNames = Inspector::Protocol::Array<String>::create();
-        for (size_t i = 0; i < databaseNamesList->length(); ++i)
-            databaseNames->addItem(databaseNamesList->item(i));
-        m_requestCallback->sendSuccess(WTFMove(databaseNames));
-    }
-
-private:
-    GetDatabaseNamesCallback(Ref<RequestDatabaseNamesCallback>&& requestCallback, const String& securityOrigin)
-        : EventListener(EventListener::CPPEventListenerType)
-        , m_requestCallback(WTFMove(requestCallback))
-        , m_securityOrigin(securityOrigin) { }
-    Ref<RequestDatabaseNamesCallback> m_requestCallback;
-    String m_securityOrigin;
-};
-
-#endif
-
 class ExecutableWithDatabase : public RefCounted<ExecutableWithDatabase> {
 public:
     ExecutableWithDatabase(ScriptExecutionContext* context)
@@ -512,29 +456,34 @@ static IDBFactory* assertIDBFactory(ErrorString& errorString, Document* document
 
 void InspectorIndexedDBAgent::requestDatabaseNames(ErrorString& errorString, const String& securityOrigin, Ref<RequestDatabaseNamesCallback>&& requestCallback)
 {
-    UNUSED_PARAM(errorString);
-    UNUSED_PARAM(securityOrigin);
-    requestCallback->sendFailure("Could not obtain database names.");
-
-#if 0 // IDBFactory::getDatabaseNames isn't implemented any more. Disable this for now.
     Frame* frame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin);
     Document* document = assertDocument(errorString, frame);
     if (!document)
         return;
 
+    auto* openingOrigin = document->securityOrigin();
+    if (!openingOrigin)
+        return;
+
+    auto* topOrigin = document->topOrigin();
+    if (!topOrigin)
+        return;
+
     IDBFactory* idbFactory = assertIDBFactory(errorString, document);
     if (!idbFactory)
         return;
 
-    ExceptionCode ec = 0;
-    RefPtr<IDBRequest> idbRequest = idbFactory->getDatabaseNames(*document, ec);
-    if (!idbRequest || ec) {
-        requestCallback->sendFailure("Could not obtain database names.");
-        return;
-    }
+    RefPtr<RequestDatabaseNamesCallback> callback = WTFMove(requestCallback);
+    idbFactory->getAllDatabaseNames(*topOrigin, *openingOrigin, [callback](const Vector<String>& databaseNames) {
+        if (!callback->isActive())
+            return;
+
+        Ref<Inspector::Protocol::Array<String>> databaseNameArray = Inspector::Protocol::Array<String>::create();
+        for (auto& databaseName : databaseNames)
+            databaseNameArray->addItem(databaseName);
 
-    idbRequest->addEventListener(eventNames().successEvent, GetDatabaseNamesCallback::create(WTFMove(requestCallback), document->securityOrigin()->toRawString()), false);
-#endif
+        callback->sendSuccess(WTFMove(databaseNameArray));
+    });
 }
 
 void InspectorIndexedDBAgent::requestDatabase(ErrorString& errorString, const String& securityOrigin, const String& databaseName, Ref<RequestDatabaseCallback>&& requestCallback)
index 6de6717..5074c81 100644 (file)
@@ -36,6 +36,7 @@
 #include "ResourceError.h"
 #include "ResourceRequest.h"
 #include "ResourceResponse.h"
+#include "SecurityOriginData.h"
 #include "SerializedScriptValue.h"
 #include "SessionID.h"
 #include "ThreadSafeDataBuffer.h"
@@ -84,6 +85,11 @@ CrossThreadCopierBase<false, false, ResourceResponse>::Type CrossThreadCopierBas
     return response.copyData();
 }
 
+CrossThreadCopierBase<false, false, SecurityOriginData>::Type CrossThreadCopierBase<false, false, SecurityOriginData>::copy(const SecurityOriginData& originData)
+{
+    return originData.isolatedCopy();
+}
+
 CrossThreadCopierBase<false, false, SessionID>::Type CrossThreadCopierBase<false, false, SessionID>::copy(const SessionID& sessionID)
 {
     return sessionID;
@@ -94,6 +100,16 @@ CrossThreadCopierBase<false, false, ThreadSafeDataBuffer>::Type CrossThreadCopie
     return ThreadSafeDataBuffer(buffer);
 }
 
+CrossThreadCopierBase<false, false, Vector<String>>::Type CrossThreadCopierBase<false, false, Vector<String>>::copy(const Vector<String>& strings)
+{
+    Vector<String> result;
+    result.reserveInitialCapacity(strings.size());
+    for (auto& string : strings)
+        result.uncheckedAppend(string.isolatedCopy());
+
+    return result;
+}
+
 #if ENABLE(INDEXED_DATABASE)
 
 IndexedDB::TransactionMode CrossThreadCopierBase<false, false, IndexedDB::TransactionMode>::copy(const IndexedDB::TransactionMode& mode)
index 40cfa3e..4d20b89 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2009, 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2014, 2015, 2016 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
@@ -35,6 +36,7 @@
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefPtr.h>
 #include <wtf/Threading.h>
+#include <wtf/text/WTFString.h>
 
 namespace WebCore {
 
@@ -48,6 +50,7 @@ class SessionID;
 class ThreadSafeDataBuffer;
 struct CrossThreadResourceResponseData;
 struct CrossThreadResourceRequestData;
+struct SecurityOriginData;
 struct ThreadableLoaderOptions;
 
 struct CrossThreadCopierBaseHelper {
@@ -134,6 +137,11 @@ template<> struct CrossThreadCopierBase<false, false, ResourceResponse> {
     static Type copy(const ResourceResponse&);
 };
 
+template<> struct CrossThreadCopierBase<false, false, SecurityOriginData> {
+    typedef SecurityOriginData Type;
+    static Type copy(const SecurityOriginData&);
+};
+
 template<> struct CrossThreadCopierBase<false, false, SessionID> {
     typedef SessionID Type;
     static Type copy(const SessionID&);
@@ -144,6 +152,11 @@ template<> struct CrossThreadCopierBase<false, false, ThreadSafeDataBuffer> {
     static Type copy(const ThreadSafeDataBuffer&);
 };
 
+template<> struct CrossThreadCopierBase<false, false, Vector<String>> {
+    typedef Vector<String> Type;
+    static Type copy(const Vector<String>&);
+};
+
 #if ENABLE(INDEXED_DATABASE)
 namespace IndexedDB {
 enum class TransactionMode;
index 30e5d04..31e9270 100644 (file)
@@ -130,6 +130,87 @@ String encodeForFileName(const String& inputString)
     return result.toString();
 }
 
+String decodeFromFilename(const String& inputString)
+{
+    unsigned length = inputString.length();
+    if (!length)
+        return inputString;
+
+    StringBuilder result;
+    result.reserveCapacity(length);
+
+    for (unsigned i = 0; i < length; ++i) {
+        if (inputString[i] != '%') {
+            result.append(inputString[i]);
+            continue;
+        }
+
+        // If the input string is a valid encoded filename, it must be at least 2 characters longer
+        // than the current index to account for this percent encoded value.
+        if (i + 2 >= length)
+            return { };
+
+        if (inputString[i+1] != '+') {
+            char value;
+            if (!hexDigitValue(inputString[i + 1], value))
+                return { };
+            LChar character = value << 4;
+
+            if (!hexDigitValue(inputString[i + 2], value))
+                return { };
+
+            result.append(character | value);
+            continue;
+        }
+
+        // If the input string is a valid encoded filename, it must be at least 5 characters longer
+        // than the current index to account for this percent encoded value.
+        if (i + 5 >= length)
+            return { };
+
+        char value;
+        if (!hexDigitValue(inputString[i + 2], value))
+            return { };
+        UChar character = value << 12;
+
+        if (!hexDigitValue(inputString[i + 3], value))
+            return { };
+        character = character | (value << 8);
+
+        if (!hexDigitValue(inputString[i + 4], value))
+            return { };
+        character = character | (value << 4);
+
+        if (!hexDigitValue(inputString[i + 5], value))
+            return { };
+
+        result.append(character | value);
+    }
+
+    return result.toString();
+}
+
+String lastComponentOfPathIgnoringTrailingSlash(const String& path)
+{
+#if PLATFORM(WIN)
+    char pathSeperator = '\\';
+#else
+    char pathSeperator = '/';
+#endif
+
+    auto position = path.reverseFind(pathSeperator);
+    if (position == notFound)
+        return path;
+
+    size_t endOfSubstring = path.length() - 1;
+    if (position == endOfSubstring) {
+        --endOfSubstring;
+        position = path.reverseFind(pathSeperator, endOfSubstring);
+    }
+
+    return path.substring(position + 1, endOfSubstring - position);
+}
+
 bool appendFileContentsToFileHandle(const String& path, PlatformFileHandle& target)
 {
     auto source = openFile(path, OpenForRead);
index f1a78df..9527da2 100644 (file)
@@ -146,6 +146,7 @@ WEBCORE_EXPORT bool getFileModificationTime(const String&, time_t& result);
 WEBCORE_EXPORT bool getFileCreationTime(const String&, time_t& result); // Not all platforms store file creation time.
 bool getFileMetadata(const String&, FileMetadata&);
 WEBCORE_EXPORT String pathByAppendingComponent(const String& path, const String& component);
+String lastComponentOfPathIgnoringTrailingSlash(const String& path);
 WEBCORE_EXPORT bool makeAllDirectories(const String& path);
 String homeDirectoryPath();
 WEBCORE_EXPORT String pathGetFileName(const String&);
@@ -159,6 +160,7 @@ bool excludeFromBackup(const String&); // Returns true if successful.
 WEBCORE_EXPORT Vector<String> listDirectory(const String& path, const String& filter = String());
 
 WEBCORE_EXPORT CString fileSystemRepresentation(const String&);
+String stringFromFileSystemRepresentation(const char*);
 
 inline bool isHandleValid(const PlatformFileHandle& handle) { return handle != invalidPlatformFileHandle; }
 
@@ -194,6 +196,7 @@ bool unloadModule(PlatformModule);
 
 // Encode a string for use within a file name.
 WEBCORE_EXPORT String encodeForFileName(const String&);
+String decodeFromFilename(const String&);
 
 #if USE(CF)
 RetainPtr<CFURLRef> pathAsURL(const String&);
index 3e540b9..1f684b6 100644 (file)
@@ -29,6 +29,7 @@
 #include "config.h"
 #include "FileSystem.h"
 
+#include <CoreFoundation/CFString.h>
 #include <wtf/RetainPtr.h>
 #include <wtf/text/CString.h>
 #include <wtf/text/WTFString.h>
@@ -54,6 +55,11 @@ CString fileSystemRepresentation(const String& path)
     return CString(buffer.data(), strlen(buffer.data()));
 }
 
+String stringFromFileSystemRepresentation(const char* fileSystemRepresentation)
+{
+    return adoptCF(CFStringCreateWithFileSystemRepresentation(kCFAllocatorDefault, fileSystemRepresentation)).get();
+}
+
 RetainPtr<CFURLRef> pathAsURL(const String& path)
 {
     CFURLPathStyle pathStyle;
index 58188ff..a0892ec 100644 (file)
@@ -54,6 +54,11 @@ String filenameToString(const char* filename)
 #endif
 }
 
+String stringFromFileSystemRepresentation(const char* fileSystemRepresentation)
+{
+    return filenameToString(fileSystemRepresentation);
+}
+
 static GUniquePtr<char> unescapedFilename(const String& path)
 {
     if (path.isEmpty())
index 91f6dfd..a8570c9 100644 (file)
@@ -32,6 +32,7 @@
 #import "WebCoreNSURLExtras.h"
 #import "WebCoreSystemInterface.h"
 #import <functional>
+#import <wtf/HexNumber.h>
 #import <wtf/ObjcRuntimeExtras.h>
 #import <wtf/RetainPtr.h>
 #import <wtf/Vector.h>
@@ -718,34 +719,6 @@ static NSString *mapHostNames(NSString *string, BOOL encode)
     return [mutableCopy autorelease];
 }
 
-static BOOL isHexDigit(char c)
-{
-    return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
-}
-
-static char hexDigit(int i)
-{
-    if (i < 0 || i > 16)
-        return '0';
-
-    return (i >= 10) ? i - 10 + 'A' : i += '0'; 
-}
-
-static int hexDigitValue(char c)
-{
-    if (c >= '0' && c <= '9')
-        return c - '0';
-
-    if (c >= 'A' && c <= 'F')
-        return c - 'A' + 10;
-
-    if (c >= 'a' && c <= 'f')
-        return c - 'a' + 10;
-
-    LOG_ERROR("illegal hex digit");
-    return 0;
-}
-
 static NSString *stringByTrimmingWhitespace(NSString *string)
 {
     NSMutableString *trimmed = [[string mutableCopy] autorelease];
@@ -831,8 +804,8 @@ static NSData *dataWithUserTypedString(NSString *string)
         UInt8 c = inBytes[i];
         if (c <= 0x20 || c >= 0x7f) {
             *p++ = '%';
-            *p++ = hexDigit(c >> 4);
-            *p++ = hexDigit(c & 0xf);
+            *p++ = uncheckedHexDigit(c >> 4);
+            *p++ = uncheckedHexDigit(c & 0xf);
             outLength += 3;
         } else {
             *p++ = c;
@@ -926,8 +899,8 @@ NSData *dataForURLComponentType(NSURL *URL, CFURLComponentType componentType)
         if (c <= 0x20 || c >= 0x7f) {
             char escaped[3];
             escaped[0] = '%';
-            escaped[1] = hexDigit(c >> 4);
-            escaped[2] = hexDigit(c & 0xf);
+            escaped[1] = uncheckedHexDigit(c >> 4);
+            escaped[2] = uncheckedHexDigit(c & 0xf);
             [resultData appendBytes:escaped length:3];    
         } else {
             char b[1];
@@ -1038,8 +1011,8 @@ static CFStringRef createStringWithEscapedUnsafeCharacters(CFStringRef string)
             
             for (CFIndex j = 0; j < offset; ++j) {
                 outBuffer.append('%');
-                outBuffer.append(hexDigit(utf8Buffer[j] >> 4));
-                outBuffer.append(hexDigit(utf8Buffer[j] & 0xf));
+                outBuffer.append(uncheckedHexDigit(utf8Buffer[j] >> 4));
+                outBuffer.append(uncheckedHexDigit(utf8Buffer[j] & 0xf));
             }
         } else {
             UChar utf16Buffer[2];
@@ -1071,7 +1044,7 @@ NSString *userVisibleString(NSURL *URL)
         unsigned char c = p[i];
         // unescape escape sequences that indicate bytes greater than 0x7f
         if (c == '%' && (i + 1 < length && isHexDigit(p[i + 1])) && i + 2 < length && isHexDigit(p[i + 2])) {
-            unsigned char u = (hexDigitValue(p[i + 1]) << 4) | hexDigitValue(p[i + 2]);
+            unsigned char u = (uncheckedHexDigitValue(p[i + 1]) << 4) | uncheckedHexDigitValue(p[i + 2]);
             if (u > 0x7f) {
                 // unescape
                 *q++ = u;
@@ -1108,8 +1081,8 @@ NSString *userVisibleString(NSURL *URL)
             unsigned char c = *p;
             if (c > 0x7f) {
                 *q++ = '%';
-                *q++ = hexDigit(c >> 4);
-                *q++ = hexDigit(c & 0xf);
+                *q++ = uncheckedHexDigit(c >> 4);
+                *q++ = uncheckedHexDigit(c & 0xf);
             } else
                 *q++ = *p;
             p++;
@@ -1152,7 +1125,7 @@ BOOL isUserVisibleURL(NSString *string)
             valid = NO;
             break;
         } else if (c == '%' && (i + 1 < length && isHexDigit(p[i + 1])) && i + 2 < length && isHexDigit(p[i + 2])) {
-            unsigned char u = (hexDigitValue(p[i + 1]) << 4) | hexDigitValue(p[i + 2]);
+            unsigned char u = (uncheckedHexDigitValue(p[i + 1]) << 4) | uncheckedHexDigitValue(p[i + 2]);
             if (u > 0x7f) {
                 valid = NO;
                 break;
index cd88f65..a61f65a 100644 (file)
@@ -301,8 +301,8 @@ String directoryName(const String& path)
 Vector<String> listDirectory(const String& path, const String& filter)
 {
     Vector<String> entries;
-    CString cpath = path.utf8();
-    CString cfilter = filter.utf8();
+    CString cpath = fileSystemRepresentation(path);
+    CString cfilter = fileSystemRepresentation(filter);
     DIR* dir = opendir(cpath.data());
     if (dir) {
         struct dirent* dp;
@@ -312,10 +312,16 @@ Vector<String> listDirectory(const String& path, const String& filter)
                 continue;
             if (fnmatch(cfilter.data(), name, 0))
                 continue;
-            char filePath[1024];
+            char filePath[PATH_MAX];
             if (static_cast<int>(sizeof(filePath) - 1) < snprintf(filePath, sizeof(filePath), "%s/%s", cpath.data(), name))
                 continue; // buffer overflow
-            entries.append(filePath);
+
+            auto string = stringFromFileSystemRepresentation(filePath);
+
+            // Some file system representations cannot be represented as a UTF-16 string,
+            // so this string might be null.
+            if (!string.isNull())
+                entries.append(WTFMove(string));
         }
         closedir(dir);
     }
index 27f32d7..a53c2f6 100644 (file)
@@ -1,3 +1,28 @@
+2016-04-27  Brady Eidson  <beidson@apple.com>
+
+        Modern IDB: Implement native IDBFactory.getAllDatabaseNames for WebInspector.
+        https://bugs.webkit.org/show_bug.cgi?id=157072
+
+        Reviewed by Alex Christensen.
+
+        Handle the process hop for the new getAllDatabaseNames call.
+        
+        * DatabaseProcess/IndexedDB/WebIDBConnectionToClient.cpp:
+        (WebKit::WebIDBConnectionToClient::didGetAllDatabaseNames):
+        (WebKit::WebIDBConnectionToClient::getAllDatabaseNames):
+        * DatabaseProcess/IndexedDB/WebIDBConnectionToClient.h:
+        * DatabaseProcess/IndexedDB/WebIDBConnectionToClient.messages.in:
+
+        * Shared/WebCrossThreadCopier.cpp:
+        (WebCore::SecurityOriginData>::copy): Deleted, as its in WebCore now.
+        * Shared/WebCrossThreadCopier.h:
+
+        * WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp:
+        (WebKit::WebIDBConnectionToServer::getAllDatabaseNames):
+        (WebKit::WebIDBConnectionToServer::didGetAllDatabaseNames):
+        * WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.h:
+        * WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.messages.in:
+
 2016-04-27  Simon Fraser  <simon.fraser@apple.com>
 
         [iOS WK2] When determining tile size, check whether ancestor UIScrollViews are actually scrollable
index aaa5a6f..fc51c50 100644 (file)
@@ -174,6 +174,11 @@ void WebIDBConnectionToClient::notifyOpenDBRequestBlocked(const WebCore::IDBReso
     send(Messages::WebIDBConnectionToServer::NotifyOpenDBRequestBlocked(requestIdentifier, oldVersion, newVersion));
 }
 
+void WebIDBConnectionToClient::didGetAllDatabaseNames(uint64_t callbackID, const Vector<String>& databaseNames)
+{
+    send(Messages::WebIDBConnectionToServer::DidGetAllDatabaseNames(callbackID, databaseNames));
+}
+
 void WebIDBConnectionToClient::deleteDatabase(const IDBRequestData& request)
 {
     DatabaseProcess::singleton().idbServer().deleteDatabase(request);
@@ -284,6 +289,11 @@ void WebIDBConnectionToClient::didFireVersionChangeEvent(uint64_t databaseConnec
     DatabaseProcess::singleton().idbServer().didFireVersionChangeEvent(databaseConnectionIdentifier, transactionIdentifier);
 }
 
+void WebIDBConnectionToClient::getAllDatabaseNames(uint64_t serverConnectionIdentifier, const WebCore::SecurityOriginData& topOrigin, const WebCore::SecurityOriginData& openingOrigin, uint64_t callbackID)
+{
+    DatabaseProcess::singleton().idbServer().getAllDatabaseNames(serverConnectionIdentifier, topOrigin, openingOrigin, callbackID);
+}
+
 } // namespace WebKit
 
 #endif // ENABLE(INDEXED_DATABASE)
index 55fd7a0..fdca0bf 100644 (file)
@@ -42,6 +42,7 @@ class IDBTransactionInfo;
 class IDBValue;
 class SerializedScriptValue;
 struct IDBKeyRangeData;
+struct SecurityOriginData;
 }
 
 namespace WebKit {
@@ -77,6 +78,8 @@ public:
     void didStartTransaction(const WebCore::IDBResourceIdentifier& transactionIdentifier, const WebCore::IDBError&) final;
     void notifyOpenDBRequestBlocked(const WebCore::IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion) final;
 
+    void didGetAllDatabaseNames(uint64_t callbackID, const Vector<String>& databaseNames) final;
+
     void ref() override { RefCounted<WebIDBConnectionToClient>::ref(); }
     void deref() override { RefCounted<WebIDBConnectionToClient>::deref(); }
 
@@ -103,6 +106,8 @@ public:
     void abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const WebCore::IDBResourceIdentifier& transactionIdentifier);
     void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const WebCore::IDBResourceIdentifier& requestIdentifier);
 
+    void getAllDatabaseNames(uint64_t serverConnectionIdentifier, const WebCore::SecurityOriginData& topOrigin, const WebCore::SecurityOriginData& openingOrigin, uint64_t callbackID);
+
     void disconnectedFromWebProcess();
 
     void didReceiveMessage(IPC::Connection&, IPC::MessageDecoder&);
index a848ff9..335ca71 100644 (file)
@@ -44,6 +44,7 @@ messages -> WebIDBConnectionToClient {
     DatabaseConnectionClosed(uint64_t databaseConnectionIdentifier);
     AbortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, WebCore::IDBResourceIdentifier transactionIdentifier);
     DidFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, WebCore::IDBResourceIdentifier requestIdentifier);
-}
 
+    GetAllDatabaseNames(uint64_t serverConnectionIdentifier, struct WebCore::SecurityOriginData topOrigin, struct WebCore::SecurityOriginData openingOrigin, uint64_t callbackID);
+}
 #endif // ENABLE(INDEXED_DATABASE) && ENABLE(DATABASE_PROCESS)
index 1a10dab..7eddbe1 100644 (file)
@@ -28,7 +28,6 @@
 #if ENABLE(INDEXED_DATABASE)
 
 #include <WebCore/IDBKeyData.h>
-#include <WebCore/SecurityOriginData.h>
 
 using namespace WebKit;
 
@@ -68,11 +67,6 @@ Vector<Vector<IDBKeyData>> CrossThreadCopierBase<false, false, Vector<Vector<IDB
     return result;
 }
 
-SecurityOriginData CrossThreadCopierBase<false, false, SecurityOriginData>::copy(const SecurityOriginData& securityOriginData)
-{
-    return securityOriginData.isolatedCopy();
-}
-
 ASCIILiteral CrossThreadCopierBase<false, false, ASCIILiteral>::copy(const ASCIILiteral& literal)
 {
     return literal;
index b41bc9c..310d5f8 100644 (file)
@@ -52,10 +52,6 @@ template<> struct CrossThreadCopierBase<false, false, WebKit::LegacyUniqueIDBDat
     }
 };
 
-template<> struct CrossThreadCopierBase<false, false, WebCore::SecurityOriginData> {
-    static WebCore::SecurityOriginData copy(const WebCore::SecurityOriginData& type);
-};
-
 template<> struct CrossThreadCopierBase<false, false, Vector<char>> {
     static Vector<char> copy(const Vector<char>&);
 };
index 8c85bd4..a123c04 100644 (file)
@@ -182,6 +182,11 @@ void WebIDBConnectionToServer::didFireVersionChangeEvent(uint64_t databaseConnec
     send(Messages::WebIDBConnectionToClient::DidFireVersionChangeEvent(databaseConnectionIdentifier, requestIdentifier));
 }
 
+void WebIDBConnectionToServer::getAllDatabaseNames(const WebCore::SecurityOriginData& topOrigin, const WebCore::SecurityOriginData& openingOrigin, uint64_t callbackID)
+{
+    send(Messages::WebIDBConnectionToClient::GetAllDatabaseNames(m_identifier, topOrigin, openingOrigin, callbackID));
+}
+
 void WebIDBConnectionToServer::didDeleteDatabase(const IDBResultData& result)
 {
     m_connectionToServer->didDeleteDatabase(result);
@@ -283,6 +288,11 @@ void WebIDBConnectionToServer::notifyOpenDBRequestBlocked(const IDBResourceIdent
     m_connectionToServer->notifyOpenDBRequestBlocked(requestIdentifier, oldVersion, newVersion);
 }
 
+void WebIDBConnectionToServer::didGetAllDatabaseNames(uint64_t callbackID, const Vector<String>& databaseNames)
+{
+    m_connectionToServer->didGetAllDatabaseNames(callbackID, databaseNames);
+}
+
 } // namespace WebKit
 
 #endif // ENABLE(INDEXED_DATABASE)
index edc5a16..78d70b1 100644 (file)
@@ -65,6 +65,7 @@ public:
     void databaseConnectionClosed(uint64_t databaseConnectionIdentifier) final;
     void abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const WebCore::IDBResourceIdentifier& transactionIdentifier) final;
     void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const WebCore::IDBResourceIdentifier& requestIdentifier) final;
+    void getAllDatabaseNames(const WebCore::SecurityOriginData& topOrigin, const WebCore::SecurityOriginData& openingOrigin, uint64_t callbackID) final;
 
     void ref() override { RefCounted<WebIDBConnectionToServer>::ref(); }
     void deref() override { RefCounted<WebIDBConnectionToServer>::deref(); }
@@ -89,6 +90,7 @@ public:
     void fireVersionChangeEvent(uint64_t uniqueDatabaseConnectionIdentifier, const WebCore::IDBResourceIdentifier& requestIdentifier, uint64_t requestedVersion);
     void didStartTransaction(const WebCore::IDBResourceIdentifier& transactionIdentifier, const WebCore::IDBError&);
     void notifyOpenDBRequestBlocked(const WebCore::IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion);
+    void didGetAllDatabaseNames(uint64_t callbackID, const Vector<String>& databaseNames);
 
     void didReceiveMessage(IPC::Connection&, IPC::MessageDecoder&);
 
index 111232a..65ec103 100644 (file)
@@ -44,6 +44,7 @@ messages -> WebIDBConnectionToServer {
     DidStartTransaction(WebCore::IDBResourceIdentifier transactionIdentifier, WebCore::IDBError error)
     NotifyOpenDBRequestBlocked(WebCore::IDBResourceIdentifier requestIdentifier, uint64_t oldVersion, uint64_t newVersion)
 
+    DidGetAllDatabaseNames(uint64_t callbackID, Vector<String> databaseNames)
 }
 
 #endif // ENABLE(INDEXED_DATABASE) && ENABLE(DATABASE_PROCESS)