Title: [246079] trunk
Revision
246079
Author
[email protected]
Date
2019-06-04 13:54:31 -0700 (Tue, 04 Jun 2019)

Log Message

WKWebsiteDataStore API fails to fetch web storage data for non-persistent data store
https://bugs.webkit.org/show_bug.cgi?id=198317
Source/WebKit:

<rdar://problem/51244662>

Reviewed by Alex Christensen.

Use LocalStorageNameSpace instead of SessionStorageNameSpace for localStorage in ephemeral session or
websiteDataStore.

Reland r245943 as test has been fixed in r246012.

* NetworkProcess/WebStorage/StorageManager.cpp:
(WebKit::StorageManager::StorageArea::isEphemeral const):
(WebKit::StorageManager::StorageArea::removeListener):
(WebKit::StorageManager::StorageArea::setItems):
(WebKit::StorageManager::StorageArea::openDatabaseAndImportItemsIfNeeded const):
(WebKit::StorageManager::LocalStorageNamespace::~LocalStorageNamespace):
(WebKit::StorageManager::LocalStorageNamespace::getOrCreateStorageArea):
(WebKit::StorageManager::LocalStorageNamespace::clearAllStorageAreas):
(WebKit::StorageManager::LocalStorageNamespace::ephemeralOrigins const):
(WebKit::StorageManager::LocalStorageNamespace::cloneTo):
(WebKit::StorageManager::StorageManager):
(WebKit::StorageManager::cloneSessionStorageNamespace):
(WebKit::StorageManager::getLocalStorageOrigins):
(WebKit::StorageManager::getLocalStorageOriginDetails):
(WebKit::StorageManager::deleteLocalStorageEntriesForOrigin):
(WebKit::StorageManager::deleteLocalStorageOriginsModifiedSince):
(WebKit::StorageManager::deleteLocalStorageEntriesForOrigins):
(WebKit::StorageManager::createLocalStorageMap):
(WebKit::StorageManager::createTransientLocalStorageMap):
(WebKit::StorageManager::createSessionStorageMap):
(WebKit::StorageManager::destroyStorageMap):
(WebKit::StorageManager::getValues):
(WebKit::StorageManager::setItem):
(WebKit::StorageManager::removeItem):
(WebKit::StorageManager::clear):
(WebKit::StorageManager::suspend):
(WebKit::StorageManager::resume):
(WebKit::StorageManager::StorageArea::isSessionStorage const): Deleted.
* NetworkProcess/WebStorage/StorageManager.h:
(): Deleted.
* WebProcess/WebStorage/StorageAreaMap.cpp:
(WebKit::StorageAreaMap::dispatchStorageEvent):
(WebKit::StorageAreaMap::dispatchSessionStorageEvent):
(WebKit::StorageAreaMap::connect):
* WebProcess/WebStorage/StorageNamespaceImpl.cpp:
(WebKit::StorageNamespaceImpl::createEphemeralLocalStorageNamespace):
(WebKit::StorageNamespaceImpl::createLocalStorageNamespace):
* WebProcess/WebStorage/StorageNamespaceImpl.h:
* WebProcess/WebStorage/WebStorageNamespaceProvider.cpp:
(WebKit::WebStorageNamespaceProvider::createLocalStorageNamespace):

Tools:

Reviewed by Alex Christensen.

* TestWebKitAPI/Tests/WebKitCocoa/WKWebsiteDatastore.mm:
(TestWebKitAPI::TEST):

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (246078 => 246079)


--- trunk/Source/WebKit/ChangeLog	2019-06-04 20:42:19 UTC (rev 246078)
+++ trunk/Source/WebKit/ChangeLog	2019-06-04 20:54:31 UTC (rev 246079)
@@ -1,3 +1,57 @@
+2019-06-04  Sihui Liu  <[email protected]>
+
+        WKWebsiteDataStore API fails to fetch web storage data for non-persistent data store
+        https://bugs.webkit.org/show_bug.cgi?id=198317
+        <rdar://problem/51244662>
+
+        Reviewed by Alex Christensen.
+
+        Use LocalStorageNameSpace instead of SessionStorageNameSpace for localStorage in ephemeral session or 
+        websiteDataStore.
+
+        Reland r245943 as test has been fixed in r246012.
+
+        * NetworkProcess/WebStorage/StorageManager.cpp:
+        (WebKit::StorageManager::StorageArea::isEphemeral const):
+        (WebKit::StorageManager::StorageArea::removeListener):
+        (WebKit::StorageManager::StorageArea::setItems):
+        (WebKit::StorageManager::StorageArea::openDatabaseAndImportItemsIfNeeded const):
+        (WebKit::StorageManager::LocalStorageNamespace::~LocalStorageNamespace):
+        (WebKit::StorageManager::LocalStorageNamespace::getOrCreateStorageArea):
+        (WebKit::StorageManager::LocalStorageNamespace::clearAllStorageAreas):
+        (WebKit::StorageManager::LocalStorageNamespace::ephemeralOrigins const):
+        (WebKit::StorageManager::LocalStorageNamespace::cloneTo):
+        (WebKit::StorageManager::StorageManager):
+        (WebKit::StorageManager::cloneSessionStorageNamespace):
+        (WebKit::StorageManager::getLocalStorageOrigins):
+        (WebKit::StorageManager::getLocalStorageOriginDetails):
+        (WebKit::StorageManager::deleteLocalStorageEntriesForOrigin):
+        (WebKit::StorageManager::deleteLocalStorageOriginsModifiedSince):
+        (WebKit::StorageManager::deleteLocalStorageEntriesForOrigins):
+        (WebKit::StorageManager::createLocalStorageMap):
+        (WebKit::StorageManager::createTransientLocalStorageMap):
+        (WebKit::StorageManager::createSessionStorageMap):
+        (WebKit::StorageManager::destroyStorageMap):
+        (WebKit::StorageManager::getValues):
+        (WebKit::StorageManager::setItem):
+        (WebKit::StorageManager::removeItem):
+        (WebKit::StorageManager::clear):
+        (WebKit::StorageManager::suspend):
+        (WebKit::StorageManager::resume):
+        (WebKit::StorageManager::StorageArea::isSessionStorage const): Deleted.
+        * NetworkProcess/WebStorage/StorageManager.h:
+        (): Deleted.
+        * WebProcess/WebStorage/StorageAreaMap.cpp:
+        (WebKit::StorageAreaMap::dispatchStorageEvent):
+        (WebKit::StorageAreaMap::dispatchSessionStorageEvent):
+        (WebKit::StorageAreaMap::connect):
+        * WebProcess/WebStorage/StorageNamespaceImpl.cpp:
+        (WebKit::StorageNamespaceImpl::createEphemeralLocalStorageNamespace):
+        (WebKit::StorageNamespaceImpl::createLocalStorageNamespace):
+        * WebProcess/WebStorage/StorageNamespaceImpl.h:
+        * WebProcess/WebStorage/WebStorageNamespaceProvider.cpp:
+        (WebKit::WebStorageNamespaceProvider::createLocalStorageNamespace):
+
 2019-06-04  Alex Christensen  <[email protected]>
 
         Uploading third-party applications from /Applications needs additional syscall access

Modified: trunk/Source/WebKit/NetworkProcess/WebStorage/StorageManager.cpp (246078 => 246079)


--- trunk/Source/WebKit/NetworkProcess/WebStorage/StorageManager.cpp	2019-06-04 20:42:19 UTC (rev 246078)
+++ trunk/Source/WebKit/NetworkProcess/WebStorage/StorageManager.cpp	2019-06-04 20:54:31 UTC (rev 246079)
@@ -63,7 +63,7 @@
     const HashMap<String, String>& items() const;
     void clear();
 
-    bool isSessionStorage() const { return !m_localStorageNamespace; }
+    bool isEphemeral() const { return !m_localStorageNamespace; }
 
 private:
     explicit StorageArea(LocalStorageNamespace*, const SecurityOriginData&, unsigned quotaInBytes);
@@ -72,7 +72,7 @@
 
     void dispatchEvents(IPC::Connection::UniqueID sourceConnection, uint64_t sourceStorageAreaID, const String& key, const String& oldValue, const String& newValue, const String& urlString) const;
 
-    // Will be null if the storage area belongs to a session storage namespace.
+    // Will be null if the storage area belongs to a session storage namespace or the storage area is in an ephemeral session.
     LocalStorageNamespace* m_localStorageNamespace;
     mutable RefPtr<LocalStorageDatabase> m_localStorageDatabase;
     mutable bool m_didImportItemsFromDatabase { false };
@@ -91,12 +91,16 @@
 
     StorageManager* storageManager() const { return &m_storageManager; }
 
-    Ref<StorageArea> getOrCreateStorageArea(SecurityOriginData&&);
+    enum class IsEphemeral : bool { No, Yes };
+    Ref<StorageArea> getOrCreateStorageArea(SecurityOriginData&&, IsEphemeral);
     void didDestroyStorageArea(StorageArea*);
 
     void clearStorageAreasMatchingOrigin(const SecurityOriginData&);
     void clearAllStorageAreas();
 
+    Vector<SecurityOriginData> ephemeralOrigins() const;
+    void cloneTo(LocalStorageNamespace& newLocalStorageNamespace);
+
 private:
     LocalStorageNamespace(StorageManager&, uint64_t storageManagerID);
 
@@ -104,8 +108,7 @@
     uint64_t m_storageNamespaceID;
     unsigned m_quotaInBytes;
 
-    // We don't hold an explicit reference to the StorageAreas; they are kept alive by the m_storageAreasByConnection map in StorageManager.
-    HashMap<SecurityOriginData, StorageArea*> m_storageAreaMap;
+    HashMap<SecurityOriginData, RefPtr<StorageArea>> m_storageAreaMap;
 };
 
 // Suggested by https://www.w3.org/TR/webstorage/#disk-space
@@ -196,7 +199,7 @@
 
 void StorageManager::StorageArea::removeListener(IPC::Connection::UniqueID connectionID, uint64_t storageMapID)
 {
-    ASSERT(isSessionStorage() || m_eventListeners.contains(std::make_pair(connectionID, storageMapID)));
+    ASSERT(isEphemeral() || m_eventListeners.contains(std::make_pair(connectionID, storageMapID)));
     m_eventListeners.remove(std::make_pair(connectionID, storageMapID));
 }
 
@@ -236,7 +239,10 @@
 
 void StorageManager::StorageArea::setItems(const HashMap<String, String>& items)
 {
-    ASSERT(!m_localStorageDatabase);
+    // Import items from web process if items are not stored on disk.
+    if (!isEphemeral())
+        return;
+
     for (auto& item : items) {
         String oldValue;
         bool quotaException;
@@ -311,9 +317,10 @@
     if (!m_localStorageNamespace)
         return;
 
+    ASSERT(m_localStorageNamespace->storageManager()->m_localStorageDatabaseTracker);
     // We open the database here even if we've already imported our items to ensure that the database is open if we need to write to it.
     if (!m_localStorageDatabase)
-        m_localStorageDatabase = LocalStorageDatabase::create(m_localStorageNamespace->storageManager()->m_queue.copyRef(), m_localStorageNamespace->storageManager()->m_localStorageDatabaseTracker.copyRef(), m_securityOrigin);
+        m_localStorageDatabase = LocalStorageDatabase::create(m_localStorageNamespace->storageManager()->m_queue.copyRef(), *m_localStorageNamespace->storageManager()->m_localStorageDatabaseTracker, m_securityOrigin);
 
     if (m_didImportItemsFromDatabase)
         return;
@@ -350,14 +357,13 @@
 
 StorageManager::LocalStorageNamespace::~LocalStorageNamespace()
 {
-    ASSERT(m_storageAreaMap.isEmpty());
 }
 
-auto StorageManager::LocalStorageNamespace::getOrCreateStorageArea(SecurityOriginData&& securityOrigin) -> Ref<StorageArea>
+auto StorageManager::LocalStorageNamespace::getOrCreateStorageArea(SecurityOriginData&& securityOrigin, IsEphemeral isEphemeral) -> Ref<StorageArea>
 {
     RefPtr<StorageArea> protectedStorageArea;
     return *m_storageAreaMap.ensure(securityOrigin, [&]() mutable {
-        protectedStorageArea = StorageArea::create(this, WTFMove(securityOrigin), m_quotaInBytes);
+        protectedStorageArea = StorageArea::create(isEphemeral == IsEphemeral::Yes ? nullptr : this, WTFMove(securityOrigin), m_quotaInBytes);
         return protectedStorageArea.get();
     }).iterator->value;
 }
@@ -383,10 +389,26 @@
 
 void StorageManager::LocalStorageNamespace::clearAllStorageAreas()
 {
-    for (auto* storageArea : m_storageAreaMap.values())
+    for (auto storageArea : m_storageAreaMap.values())
         storageArea->clear();
 }
 
+Vector<SecurityOriginData> StorageManager::LocalStorageNamespace::ephemeralOrigins() const
+{
+    Vector<SecurityOriginData> origins;
+    for (const auto& storageArea : m_storageAreaMap.values()) {
+        if (!storageArea->items().isEmpty())
+            origins.append(storageArea->securityOrigin());
+    }
+    return origins;
+}
+
+void StorageManager::LocalStorageNamespace::cloneTo(LocalStorageNamespace& newLocalStorageNamespace)
+{
+    for (auto& pair : m_storageAreaMap)
+        newLocalStorageNamespace.m_storageAreaMap.add(pair.key, pair.value->clone());
+}
+
 class StorageManager::SessionStorageNamespace : public ThreadSafeRefCounted<SessionStorageNamespace> {
 public:
     static Ref<SessionStorageNamespace> create(unsigned quotaInBytes);
@@ -483,11 +505,11 @@
 
 StorageManager::StorageManager(const String& localStorageDirectory)
     : m_queue(WorkQueue::create("com.apple.WebKit.StorageManager"))
-    , m_localStorageDatabaseTracker(LocalStorageDatabaseTracker::create(m_queue.copyRef(), localStorageDirectory))
-    , m_isEphemeral(localStorageDirectory.isNull())
 {
     // Make sure the encoding is initialized before we start dispatching things to the queue.
     UTF8Encoding();
+    if (!localStorageDirectory.isNull())
+        m_localStorageDatabaseTracker = LocalStorageDatabaseTracker::create(m_queue.copyRef(), localStorageDirectory);
 }
 
 StorageManager::~StorageManager()
@@ -548,6 +570,13 @@
         ASSERT(newSessionStorageNamespace);
 
         sessionStorageNamespace->cloneTo(*newSessionStorageNamespace);
+
+        if (!m_localStorageDatabaseTracker) {
+            if (auto* localStorageNamespace = m_localStorageNamespaces.get(storageNamespaceID)) {
+                LocalStorageNamespace* newlocalStorageNamespace = getOrCreateLocalStorageNamespace(newStorageNamespaceID);
+                localStorageNamespace->cloneTo(*newlocalStorageNamespace);
+            }
+        }
     });
 }
 
@@ -629,8 +658,15 @@
     m_queue->dispatch([this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)]() mutable {
         HashSet<SecurityOriginData> origins;
 
-        for (auto& origin : m_localStorageDatabaseTracker->origins())
-            origins.add(origin);
+        if (m_localStorageDatabaseTracker) {
+            for (auto& origin : m_localStorageDatabaseTracker->origins())
+                origins.add(origin);
+        } else {
+            for (const auto& localStorageNameSpace : m_localStorageNamespaces.values()) {
+                for (auto& origin : localStorageNameSpace->ephemeralOrigins())
+                    origins.add(origin);
+            }
+        }
 
         for (auto& transientLocalStorageNamespace : m_transientLocalStorageNamespaces.values()) {
             for (auto& origin : transientLocalStorageNamespace->origins())
@@ -646,7 +682,9 @@
 void StorageManager::getLocalStorageOriginDetails(Function<void(Vector<LocalStorageDatabaseTracker::OriginDetails>&&)>&& completionHandler)
 {
     m_queue->dispatch([this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)]() mutable {
-        auto originDetails = m_localStorageDatabaseTracker->originDetails();
+        Vector<LocalStorageDatabaseTracker::OriginDetails> originDetails;
+        if (m_localStorageDatabaseTracker)
+            originDetails = m_localStorageDatabaseTracker->originDetails();
 
         RunLoop::main().dispatch([originDetails = WTFMove(originDetails), completionHandler = WTFMove(completionHandler)]() mutable {
             completionHandler(WTFMove(originDetails));
@@ -663,7 +701,8 @@
         for (auto& transientLocalStorageNamespace : m_transientLocalStorageNamespaces.values())
             transientLocalStorageNamespace->clearStorageAreasMatchingOrigin(copiedOrigin);
 
-        m_localStorageDatabaseTracker->deleteDatabaseWithOrigin(copiedOrigin);
+        if (m_localStorageDatabaseTracker)
+            m_localStorageDatabaseTracker->deleteDatabaseWithOrigin(copiedOrigin);
     });
 }
 
@@ -670,16 +709,21 @@
 void StorageManager::deleteLocalStorageOriginsModifiedSince(WallTime time, Function<void()>&& completionHandler)
 {
     m_queue->dispatch([this, protectedThis = makeRef(*this), time, completionHandler = WTFMove(completionHandler)]() mutable {
-        auto originsToDelete = m_localStorageDatabaseTracker->databasesModifiedSince(time);
-        
-        for (auto& transientLocalStorageNamespace : m_transientLocalStorageNamespaces.values())
-            transientLocalStorageNamespace->clearAllStorageAreas();
+        if (m_localStorageDatabaseTracker) {
+            auto originsToDelete = m_localStorageDatabaseTracker->databasesModifiedSince(time);
+            
+            for (auto& transientLocalStorageNamespace : m_transientLocalStorageNamespaces.values())
+                transientLocalStorageNamespace->clearAllStorageAreas();
 
-        for (const auto& origin : originsToDelete) {
+            for (const auto& origin : originsToDelete) {
+                for (auto& localStorageNamespace : m_localStorageNamespaces.values())
+                    localStorageNamespace->clearStorageAreasMatchingOrigin(origin);
+                
+                m_localStorageDatabaseTracker->deleteDatabaseWithOrigin(origin);
+            }
+        } else {
             for (auto& localStorageNamespace : m_localStorageNamespaces.values())
-                localStorageNamespace->clearStorageAreasMatchingOrigin(origin);
-            
-            m_localStorageDatabaseTracker->deleteDatabaseWithOrigin(origin);
+                localStorageNamespace->clearAllStorageAreas();
         }
 
         RunLoop::main().dispatch(WTFMove(completionHandler));
@@ -702,7 +746,8 @@
             for (auto& transientLocalStorageNamespace : m_transientLocalStorageNamespaces.values())
                 transientLocalStorageNamespace->clearStorageAreasMatchingOrigin(origin);
 
-            m_localStorageDatabaseTracker->deleteDatabaseWithOrigin(origin);
+            if (m_localStorageDatabaseTracker)
+                m_localStorageDatabaseTracker->deleteDatabaseWithOrigin(origin);
         }
 
         RunLoop::main().dispatch(WTFMove(completionHandler));
@@ -712,7 +757,6 @@
 void StorageManager::createLocalStorageMap(IPC::Connection& connection, uint64_t storageMapID, uint64_t storageNamespaceID, SecurityOriginData&& securityOriginData)
 {
     m_queue->dispatch([this, protectedThis = makeRef(*this), connectionID = connection.uniqueID(), storageMapID, storageNamespaceID, securityOriginData = securityOriginData.isolatedCopy()]() mutable {
-        ASSERT(!m_isEphemeral);
         std::pair<IPC::Connection::UniqueID, uint64_t> connectionAndStorageMapIDPair(connectionID, storageMapID);
 
         ASSERT((HashMap<std::pair<IPC::Connection::UniqueID, uint64_t>, RefPtr<StorageArea>>::isValidKey(connectionAndStorageMapIDPair)));
@@ -724,7 +768,7 @@
         LocalStorageNamespace* localStorageNamespace = getOrCreateLocalStorageNamespace(storageNamespaceID);
         ASSERT(localStorageNamespace);
 
-        auto storageArea = localStorageNamespace->getOrCreateStorageArea(WTFMove(securityOriginData));
+        auto storageArea = localStorageNamespace->getOrCreateStorageArea(WTFMove(securityOriginData), m_localStorageDatabaseTracker ? StorageManager::LocalStorageNamespace::IsEphemeral::No : StorageManager::LocalStorageNamespace::IsEphemeral::Yes);
         storageArea->addListener(connectionID, storageMapID);
 
         result.iterator->value = WTFMove(storageArea);
@@ -742,7 +786,7 @@
             if (it->key.first != connectionID)
                 continue;
             Ref<StorageArea> area = *it->value;
-            if (!area->isSessionStorage())
+            if (!area->isEphemeral())
                 continue;
             if (!origin.securityOrigin()->isSameSchemeHostPort(area->securityOrigin().securityOrigin().get()))
                 continue;
@@ -772,11 +816,6 @@
 void StorageManager::createSessionStorageMap(IPC::Connection& connection, uint64_t storageMapID, uint64_t storageNamespaceID, SecurityOriginData&& securityOriginData)
 {
     m_queue->dispatch([this, protectedThis = makeRef(*this), connectionID = connection.uniqueID(), storageMapID, storageNamespaceID, securityOriginData = securityOriginData.isolatedCopy()]() mutable {
-        if (m_isEphemeral) {
-            m_ephemeralStorage.add(securityOriginData, WebCore::StorageMap::create(localStorageDatabaseQuotaInBytes));
-            return;
-        }
-
         ASSERT(m_sessionStorageNamespaces.isValidKey(storageNamespaceID));
 
         SessionStorageNamespace* sessionStorageNamespace = m_sessionStorageNamespaces.get(storageNamespaceID);
@@ -814,7 +853,7 @@
         it->value->removeListener(connectionID, storageMapID);
 
         // Don't remove session storage maps. The web process may reconnect and expect the data to still be around.
-        if (it->value->isSessionStorage())
+        if (it->value->isEphemeral())
             return;
 
         m_storageAreasByConnection.remove(connectionAndStorageMapIDPair);
@@ -832,14 +871,11 @@
 {
     m_queue->dispatch([this, protectedThis = makeRef(*this), connection = makeRef(connection), securityOriginData = securityOriginData.isolatedCopy(), storageMapID, storageMapSeed, completionHandler = WTFMove(completionHandler)]() mutable {
         auto* storageArea = findStorageArea(connection.get(), storageMapID);
-        if (!storageArea) {
-            if (m_isEphemeral) {
-                if (auto storageMap = m_ephemeralStorage.get(securityOriginData))
-                    return didGetValues(connection.get(), storageMapID, storageMap->items(), WTFMove(completionHandler));
-            }
-            // This is a session storage area for a page that has already been closed. Ignore it.
+
+        // This is a session storage area for a page that has already been closed. Ignore it.
+        if (!storageArea)
             return didGetValues(connection.get(), storageMapID, { }, WTFMove(completionHandler));
-        }
+
         didGetValues(connection.get(), storageMapID, storageArea->items(), WTFMove(completionHandler));
         connection->send(Messages::StorageAreaMap::DidGetValues(storageMapSeed), storageMapID);
     });
@@ -849,17 +885,10 @@
 {
     m_queue->dispatch([this, protectedThis = makeRef(*this), connection = makeRef(connection), securityOriginData = securityOriginData.isolatedCopy(), storageMapID, sourceStorageAreaID, storageMapSeed, key = key.isolatedCopy(), value = value.isolatedCopy(), urlString = urlString.isolatedCopy()]() mutable {
         auto* storageArea = findStorageArea(connection.get(), storageMapID);
-        if (!storageArea) {
-            if (m_isEphemeral) {
-                if (auto storageMap = m_ephemeralStorage.get(securityOriginData)) {
-                    String oldValue;
-                    bool quotaException;
-                    storageMap->setItem(key, value, oldValue, quotaException);
-                }
-            }
-            // This is a session storage area for a page that has already been closed. Ignore it.
+
+        // This is a session storage area for a page that has already been closed. Ignore it.
+        if (!storageArea)
             return;
-        }
 
         bool quotaError;
         storageArea->setItem(connection->uniqueID(), sourceStorageAreaID, key, value, urlString, quotaError);
@@ -879,16 +908,10 @@
 {
     m_queue->dispatch([this, protectedThis = makeRef(*this), connection = makeRef(connection), securityOriginData = securityOriginData.isolatedCopy(), storageMapID, sourceStorageAreaID, storageMapSeed, key = key.isolatedCopy(), urlString = urlString.isolatedCopy()]() mutable {
         auto* storageArea = findStorageArea(connection.get(), storageMapID);
-        if (!storageArea) {
-            if (m_isEphemeral) {
-                if (auto storageMap = m_ephemeralStorage.get(securityOriginData)) {
-                    String oldValue;
-                    storageMap->removeItem(key, oldValue);
-                }
-            }
-            // This is a session storage area for a page that has already been closed. Ignore it.
+
+        // This is a session storage area for a page that has already been closed. Ignore it.
+        if (!storageArea)
             return;
-        }
 
         storageArea->removeItem(connection->uniqueID(), sourceStorageAreaID, key, urlString);
         connection->send(Messages::StorageAreaMap::DidRemoveItem(storageMapSeed, key), storageMapID);
@@ -899,12 +922,10 @@
 {
     m_queue->dispatch([this, protectedThis = makeRef(*this), connection = makeRef(connection), securityOriginData = securityOriginData.isolatedCopy(), storageMapID, sourceStorageAreaID, storageMapSeed, urlString = urlString.isolatedCopy()]() mutable {
         auto* storageArea = findStorageArea(connection.get(), storageMapID);
-        if (!storageArea) {
-            if (m_isEphemeral)
-                m_ephemeralStorage.remove(securityOriginData);
-            // This is a session storage area for a page that has already been closed. Ignore it.
+
+        // This is a session storage area for a page that has already been closed. Ignore it.
+        if (!storageArea)
             return;
-        }
 
         storageArea->clear(connection->uniqueID(), sourceStorageAreaID, urlString);
         connection->send(Messages::StorageAreaMap::DidClear(storageMapSeed), storageMapID);
@@ -931,7 +952,7 @@
 
 void StorageManager::suspend(CompletionHandler<void()>&& completionHandler)
 {
-    if (m_isEphemeral)
+    if (!m_localStorageDatabaseTracker)
         return;
 
     Locker<Lock> stateLocker(m_stateLock);
@@ -956,7 +977,7 @@
 
 void StorageManager::resume()
 {
-    if (m_isEphemeral)
+    if (!m_localStorageDatabaseTracker)
         return;
 
     Locker<Lock> stateLocker(m_stateLock);

Modified: trunk/Source/WebKit/NetworkProcess/WebStorage/StorageManager.h (246078 => 246079)


--- trunk/Source/WebKit/NetworkProcess/WebStorage/StorageManager.h	2019-06-04 20:42:19 UTC (rev 246078)
+++ trunk/Source/WebKit/NetworkProcess/WebStorage/StorageManager.h	2019-06-04 20:54:31 UTC (rev 246079)
@@ -103,7 +103,7 @@
 
     Ref<WorkQueue> m_queue;
 
-    Ref<LocalStorageDatabaseTracker> m_localStorageDatabaseTracker;
+    RefPtr<LocalStorageDatabaseTracker> m_localStorageDatabaseTracker;
     HashMap<uint64_t, RefPtr<LocalStorageNamespace>> m_localStorageNamespaces;
 
     HashMap<std::pair<uint64_t, WebCore::SecurityOriginData>, RefPtr<TransientLocalStorageNamespace>> m_transientLocalStorageNamespaces;
@@ -113,9 +113,6 @@
 
     HashMap<std::pair<IPC::Connection::UniqueID, uint64_t>, RefPtr<StorageArea>> m_storageAreasByConnection;
 
-    HashMap<WebCore::SecurityOriginData, Ref<WebCore::StorageMap>> m_ephemeralStorage;
-    bool m_isEphemeral { false };
-
     enum class State {
         Running,
         WillSuspend,

Modified: trunk/Source/WebKit/WebProcess/WebStorage/StorageAreaMap.cpp (246078 => 246079)


--- trunk/Source/WebKit/WebProcess/WebStorage/StorageAreaMap.cpp	2019-06-04 20:42:19 UTC (rev 246078)
+++ trunk/Source/WebKit/WebProcess/WebStorage/StorageAreaMap.cpp	2019-06-04 20:54:31 UTC (rev 246079)
@@ -294,7 +294,7 @@
         applyChange(key, newValue);
     }
 
-    if (storageType() == StorageType::Session)
+    if (storageType() == StorageType::Session || storageType() == StorageType::EphemeralLocal)
         dispatchSessionStorageEvent(sourceStorageAreaID, key, oldValue, newValue, urlString);
     else
         dispatchLocalStorageEvent(sourceStorageAreaID, key, oldValue, newValue, urlString);
@@ -307,9 +307,7 @@
 
 void StorageAreaMap::dispatchSessionStorageEvent(uint64_t sourceStorageAreaID, const String& key, const String& oldValue, const String& newValue, const String& urlString)
 {
-    ASSERT(storageType() == StorageType::Session);
-
-    // Namespace IDs for session storage namespaces are equivalent to web page IDs
+    // Namespace IDs for session storage namespaces and ephemeral local storage namespaces are equivalent to web page IDs
     // so we can get the right page here.
     WebPage* webPage = WebProcess::singleton().webPage(makeObjectIdentifier<PageIdentifierType>(m_storageNamespaceID));
     if (!webPage)
@@ -377,6 +375,7 @@
 
     switch (m_storageType) {
     case StorageType::Local:
+    case StorageType::EphemeralLocal:
     case StorageType::TransientLocal:
         if (SecurityOrigin* topLevelOrigin = m_storageNamespace->topLevelOrigin())
             WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::StorageManager::CreateTransientLocalStorageMap(m_storageMapID, m_storageNamespace->storageNamespaceID(), topLevelOrigin->data(), m_securityOrigin->data()), 0);
@@ -385,14 +384,10 @@
         break;
     case StorageType::Session:
         WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::StorageManager::CreateSessionStorageMap(m_storageMapID, m_storageNamespace->storageNamespaceID(), m_securityOrigin->data()), 0);
-        if (m_storageMap)
-            WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::StorageManager::SetItems(m_storageMapID, m_storageMap->items()), 0);
-        break;
-    case StorageType::EphemeralLocal:
-        ASSERT_NOT_REACHED();
-        return;
     }
 
+    if (m_storageMap)
+        WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::StorageManager::SetItems(m_storageMapID, m_storageMap->items()), 0);
     m_isDisconnected = false;
 }
 

Modified: trunk/Source/WebKit/WebProcess/WebStorage/StorageNamespaceImpl.cpp (246078 => 246079)


--- trunk/Source/WebKit/WebProcess/WebStorage/StorageNamespaceImpl.cpp	2019-06-04 20:42:19 UTC (rev 246078)
+++ trunk/Source/WebKit/WebProcess/WebStorage/StorageNamespaceImpl.cpp	2019-06-04 20:54:31 UTC (rev 246079)
@@ -47,12 +47,12 @@
 
 Ref<StorageNamespaceImpl> StorageNamespaceImpl::createEphemeralLocalStorageNamespace(uint64_t identifier, unsigned quotaInBytes)
 {
-    return createSessionStorageNamespace(identifier, quotaInBytes);
+    return createLocalStorageNamespace(identifier, quotaInBytes, IsEphemeral::Yes);
 }
 
-Ref<StorageNamespaceImpl> StorageNamespaceImpl::createLocalStorageNamespace(uint64_t identifier, unsigned quotaInBytes)
+Ref<StorageNamespaceImpl> StorageNamespaceImpl::createLocalStorageNamespace(uint64_t identifier, unsigned quotaInBytes, IsEphemeral isEphemeral)
 {
-    return adoptRef(*new StorageNamespaceImpl(StorageType::Local, identifier, nullptr, quotaInBytes));
+    return adoptRef(*new StorageNamespaceImpl(isEphemeral == IsEphemeral::Yes ? StorageType::EphemeralLocal : StorageType::Local, identifier, nullptr, quotaInBytes));
 }
 
 Ref<StorageNamespaceImpl> StorageNamespaceImpl::createTransientLocalStorageNamespace(uint64_t identifier, WebCore::SecurityOrigin& topLevelOrigin, uint64_t quotaInBytes)

Modified: trunk/Source/WebKit/WebProcess/WebStorage/StorageNamespaceImpl.h (246078 => 246079)


--- trunk/Source/WebKit/WebProcess/WebStorage/StorageNamespaceImpl.h	2019-06-04 20:42:19 UTC (rev 246078)
+++ trunk/Source/WebKit/WebProcess/WebStorage/StorageNamespaceImpl.h	2019-06-04 20:54:31 UTC (rev 246079)
@@ -41,7 +41,9 @@
 public:
     static Ref<StorageNamespaceImpl> createSessionStorageNamespace(uint64_t identifier, unsigned quotaInBytes);
     static Ref<StorageNamespaceImpl> createEphemeralLocalStorageNamespace(uint64_t identifier, unsigned quotaInBytes);
-    static Ref<StorageNamespaceImpl> createLocalStorageNamespace(uint64_t identifier, unsigned quotaInBytes);
+
+    enum class IsEphemeral : bool { No, Yes };
+    static Ref<StorageNamespaceImpl> createLocalStorageNamespace(uint64_t identifier, unsigned quotaInBytes, IsEphemeral isEphemeral);
     static Ref<StorageNamespaceImpl> createTransientLocalStorageNamespace(uint64_t identifier, WebCore::SecurityOrigin& topLevelOrigin, uint64_t quotaInBytes);
 
     virtual ~StorageNamespaceImpl();

Modified: trunk/Source/WebKit/WebProcess/WebStorage/WebStorageNamespaceProvider.cpp (246078 => 246079)


--- trunk/Source/WebKit/WebProcess/WebStorage/WebStorageNamespaceProvider.cpp	2019-06-04 20:42:19 UTC (rev 246078)
+++ trunk/Source/WebKit/WebProcess/WebStorage/WebStorageNamespaceProvider.cpp	2019-06-04 20:54:31 UTC (rev 246079)
@@ -77,7 +77,7 @@
 
 Ref<WebCore::StorageNamespace> WebStorageNamespaceProvider::createLocalStorageNamespace(unsigned quota)
 {
-    return StorageNamespaceImpl::createLocalStorageNamespace(m_identifier, quota);
+    return StorageNamespaceImpl::createLocalStorageNamespace(m_identifier, quota, StorageNamespaceImpl::IsEphemeral::No);
 }
 
 Ref<WebCore::StorageNamespace> WebStorageNamespaceProvider::createTransientLocalStorageNamespace(WebCore::SecurityOrigin& topLevelOrigin, unsigned quota)

Modified: trunk/Tools/ChangeLog (246078 => 246079)


--- trunk/Tools/ChangeLog	2019-06-04 20:42:19 UTC (rev 246078)
+++ trunk/Tools/ChangeLog	2019-06-04 20:54:31 UTC (rev 246079)
@@ -1,3 +1,13 @@
+2019-06-04  Sihui Liu  <[email protected]>
+
+        WKWebsiteDataStore API fails to fetch web storage data for non-persistent data store
+        https://bugs.webkit.org/show_bug.cgi?id=198317
+
+        Reviewed by Alex Christensen.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/WKWebsiteDatastore.mm:
+        (TestWebKitAPI::TEST):
+
 2019-06-04  Takashi Komori  <[email protected]>
 
         [WinCairo] Implement cpu and memory measuring functions.

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebsiteDatastore.mm (246078 => 246079)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebsiteDatastore.mm	2019-06-04 20:42:19 UTC (rev 246078)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebsiteDatastore.mm	2019-06-04 20:54:31 UTC (rev 246079)
@@ -350,4 +350,46 @@
     [configuration setSourceApplicationSecondaryIdentifier:@"com.apple.Safari"];
 }
 
+TEST(WKWebsiteDataStore, FetchNonPersistentWebStorage)
+{
+    auto nonPersistentDataStore = [WKWebsiteDataStore nonPersistentDataStore];
+    auto configuration = adoptNS([WKWebViewConfiguration new]);
+    [configuration setWebsiteDataStore:nonPersistentDataStore];
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+    auto navigationDelegate = adoptNS([[NavigationTestDelegate alloc] init]);
+    [webView setNavigationDelegate:navigationDelegate.get()];
+    [webView loadHTMLString:@"<script>sessionStorage.setItem('session', 'storage');localStorage.setItem('local', 'storage');</script>" baseURL:[NSURL URLWithString:@"http://localhost"]];
+    [navigationDelegate waitForDidFinishNavigation];
+
+    readyToContinue = false;
+    [webView evaluateJavaScript:@"window.sessionStorage.getItem('session')" completionHandler:^(id result, NSError *) {
+        EXPECT_TRUE([@"storage" isEqualToString:result]);
+        readyToContinue = true;
+    }];
+    TestWebKitAPI::Util::run(&readyToContinue);
+
+    readyToContinue = false;
+    [webView evaluateJavaScript:@"window.localStorage.getItem('local')" completionHandler:^(id result, NSError *) {
+        EXPECT_TRUE([@"storage" isEqualToString:result]);
+        readyToContinue = true;
+    }];
+    TestWebKitAPI::Util::run(&readyToContinue);
+
+    readyToContinue = false;
+    [nonPersistentDataStore fetchDataRecordsOfTypes:[NSSet setWithObject:WKWebsiteDataTypeSessionStorage] completionHandler:^(NSArray<WKWebsiteDataRecord *> *dataRecords) {
+        EXPECT_EQ((int)dataRecords.count, 1);
+        EXPECT_TRUE([[[dataRecords objectAtIndex:0] displayName] isEqualToString:@"localhost"]);
+        readyToContinue = true;
+    }];
+    TestWebKitAPI::Util::run(&readyToContinue);
+
+    readyToContinue = false;
+    [nonPersistentDataStore fetchDataRecordsOfTypes:[NSSet setWithObject:WKWebsiteDataTypeLocalStorage] completionHandler:^(NSArray<WKWebsiteDataRecord *> *dataRecords) {
+        EXPECT_EQ((int)dataRecords.count, 1);
+        EXPECT_TRUE([[[dataRecords objectAtIndex:0] displayName] isEqualToString:@"localhost"]);
+        readyToContinue = true;
+    }];
+    TestWebKitAPI::Util::run(&readyToContinue);
 }
+
+}
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to