Title: [201693] trunk/Source/WebCore
Revision
201693
Author
[email protected]
Date
2016-06-04 20:46:42 -0700 (Sat, 04 Jun 2016)

Log Message

Modern IDB: Crash seen in IDBConnectionProxy::putOrAdd on GuardMalloc bot
https://bugs.webkit.org/show_bug.cgi?id=158124

Reviewed by Darin Adler.

No new tests (Covered by existing test configurations).

* Modules/indexeddb/IDBTransaction.cpp:
(WebCore::IDBTransaction::putOrAddOnServer):

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

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

* bindings/js/SerializedScriptValue.cpp:
(WebCore::SerializedScriptValue::writeBlobsToDiskForIndexedDB):
* bindings/js/SerializedScriptValue.h:

* platform/network/BlobRegistry.h:
* platform/network/BlobRegistryImpl.cpp:
(WebCore::BlobRegistryImpl::writeBlobsToTemporaryFiles):
* platform/network/BlobRegistryImpl.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (201692 => 201693)


--- trunk/Source/WebCore/ChangeLog	2016-06-05 00:59:40 UTC (rev 201692)
+++ trunk/Source/WebCore/ChangeLog	2016-06-05 03:46:42 UTC (rev 201693)
@@ -1,3 +1,30 @@
+2016-06-04  Brady Eidson  <[email protected]>
+
+        Modern IDB: Crash seen in IDBConnectionProxy::putOrAdd on GuardMalloc bot
+        https://bugs.webkit.org/show_bug.cgi?id=158124
+
+        Reviewed by Darin Adler.
+
+        No new tests (Covered by existing test configurations).
+
+        * Modules/indexeddb/IDBTransaction.cpp:
+        (WebCore::IDBTransaction::putOrAddOnServer):
+        
+        * Modules/indexeddb/client/IDBConnectionProxy.cpp:
+        (WebCore::IDBClient::IDBConnectionProxy::putOrAdd):
+        
+        * Modules/indexeddb/client/IDBConnectionProxy.h:
+        (WebCore::IDBClient::IDBConnectionProxy::callConnectionOnMainThread):
+        
+        * bindings/js/SerializedScriptValue.cpp:
+        (WebCore::SerializedScriptValue::writeBlobsToDiskForIndexedDB):
+        * bindings/js/SerializedScriptValue.h:
+        
+        * platform/network/BlobRegistry.h:
+        * platform/network/BlobRegistryImpl.cpp:
+        (WebCore::BlobRegistryImpl::writeBlobsToTemporaryFiles):
+        * platform/network/BlobRegistryImpl.h:
+
 2016-06-03  Ada Chan  <[email protected]>
 
         REGRESSION (r201474): Should set overflow: hidden on -webkit-media-controls when placeholder is showing

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp (201692 => 201693)


--- trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp	2016-06-05 00:59:40 UTC (rev 201692)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp	2016-06-05 03:46:42 UTC (rev 201693)
@@ -966,20 +966,18 @@
         return;
     }
 
-    RefPtr<IDBTransaction> protectedThis(this);
-    RefPtr<IDBClient::TransactionOperation> protectedOperation(&operation);
-    value->writeBlobsToDiskForIndexedDB([protectedThis = WTFMove(protectedThis), this, protectedOperation = WTFMove(protectedOperation), key = WTFMove(key), overwriteMode](const IDBValue& idbValue) mutable {
+    value->writeBlobsToDiskForIndexedDB([protectedThis = Ref<IDBTransaction>(*this), this, protectedOperation = Ref<IDBClient::TransactionOperation>(operation), keyData = IDBKeyData(key.get()).isolatedCopy(), overwriteMode](const IDBValue& idbValue) mutable {
         ASSERT(currentThread() == originThreadID());
         ASSERT(isMainThread());
         if (idbValue.data().data()) {
-            m_database->connectionProxy().putOrAdd(*protectedOperation, key.get(), idbValue, overwriteMode);
+            m_database->connectionProxy().putOrAdd(protectedOperation.get(), WTFMove(keyData), idbValue, overwriteMode);
             return;
         }
 
         // If the IDBValue doesn't have any data, then something went wrong writing the blobs to disk.
         // In that case, we cannot successfully store this record, so we callback with an error.
         auto result = IDBResultData::error(protectedOperation->identifier(), { IDBDatabaseException::UnknownError, ASCIILiteral("Error preparing Blob/File data to be stored in object store") });
-        callOnMainThread([protectedThis = WTFMove(protectedThis), protectedOperation = WTFMove(protectedOperation), result = WTFMove(result)]() {
+        callOnMainThread([protectedThis = WTFMove(protectedThis), protectedOperation = WTFMove(protectedOperation), result = WTFMove(result)]() mutable {
             protectedOperation->completed(result);
         });
     });

Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.cpp (201692 => 201693)


--- trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.cpp	2016-06-05 00:59:40 UTC (rev 201692)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.cpp	2016-06-05 03:46:42 UTC (rev 201693)
@@ -156,12 +156,12 @@
     callConnectionOnMainThread(&IDBConnectionToServer::deleteIndex, requestData, WTFMove(objectStoreIdentifier), indexName);
 }
 
-void IDBConnectionProxy::putOrAdd(TransactionOperation& operation, IDBKey* key, const IDBValue& value, const IndexedDB::ObjectStoreOverwriteMode mode)
+void IDBConnectionProxy::putOrAdd(TransactionOperation& operation, IDBKeyData&& keyData, const IDBValue& value, const IndexedDB::ObjectStoreOverwriteMode mode)
 {
     const IDBRequestData requestData(operation);
     saveOperation(operation);
 
-    callConnectionOnMainThread(&IDBConnectionToServer::putOrAdd, requestData, IDBKeyData(key), value, mode);
+    callConnectionOnMainThread(&IDBConnectionToServer::putOrAdd, requestData, keyData, value, mode);
 }
 
 void IDBConnectionProxy::getRecord(TransactionOperation& operation, const IDBKeyRangeData& keyRange)

Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.h (201692 => 201693)


--- trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.h	2016-06-05 00:59:40 UTC (rev 201692)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.h	2016-06-05 03:46:42 UTC (rev 201693)
@@ -70,7 +70,7 @@
     void clearObjectStore(TransactionOperation&, uint64_t objectStoreIdentifier);
     void createIndex(TransactionOperation&, const IDBIndexInfo&);
     void deleteIndex(TransactionOperation&, uint64_t objectStoreIdentifier, const String& indexName);
-    void putOrAdd(TransactionOperation&, IDBKey*, const IDBValue&, const IndexedDB::ObjectStoreOverwriteMode);
+    void putOrAdd(TransactionOperation&, IDBKeyData&&, const IDBValue&, const IndexedDB::ObjectStoreOverwriteMode);
     void getRecord(TransactionOperation&, const IDBKeyRangeData&);
     void getCount(TransactionOperation&, const IDBKeyRangeData&);
     void deleteRecord(TransactionOperation&, const IDBKeyRangeData&);
@@ -124,7 +124,7 @@
     void callConnectionOnMainThread(void (IDBConnectionToServer::*method)(Parameters...), Arguments&&... arguments)
     {
         if (isMainThread())
-            (m_connectionToServer.*method)(arguments...);
+            (m_connectionToServer.*method)(std::forward<Arguments>(arguments)...);
         else
             postMainThreadTask(m_connectionToServer, method, arguments...);
     }

Modified: trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp (201692 => 201693)


--- trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp	2016-06-05 00:59:40 UTC (rev 201692)
+++ trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp	2016-06-05 03:46:42 UTC (rev 201693)
@@ -2796,7 +2796,7 @@
     return result;
 }
 
-void SerializedScriptValue::writeBlobsToDiskForIndexedDB(std::function<void (const IDBValue&)> completionHandler)
+void SerializedScriptValue::writeBlobsToDiskForIndexedDB(NoncopyableFunction<void (const IDBValue&)>&& completionHandler)
 {
     ASSERT(isMainThread());
     ASSERT(hasBlobURLs());

Modified: trunk/Source/WebCore/bindings/js/SerializedScriptValue.h (201692 => 201693)


--- trunk/Source/WebCore/bindings/js/SerializedScriptValue.h	2016-06-05 00:59:40 UTC (rev 201692)
+++ trunk/Source/WebCore/bindings/js/SerializedScriptValue.h	2016-06-05 03:46:42 UTC (rev 201693)
@@ -31,6 +31,7 @@
 #include <runtime/ArrayBuffer.h>
 #include <runtime/JSCJSValue.h>
 #include <wtf/Forward.h>
+#include <wtf/NoncopyableFunction.h>
 #include <wtf/RefCounted.h>
 #include <wtf/text/WTFString.h>
 
@@ -86,7 +87,7 @@
 
 #if ENABLE(INDEXED_DATABASE)
     Vector<String> blobURLsIsolatedCopy() const;
-    void writeBlobsToDiskForIndexedDB(std::function<void (const IDBValue&)> completionHandler);
+    void writeBlobsToDiskForIndexedDB(NoncopyableFunction<void (const IDBValue&)>&& completionHandler);
     IDBValue writeBlobsToDiskForIndexedDBSynchronously();
 #endif // ENABLE(INDEXED_DATABASE)
 

Modified: trunk/Source/WebCore/platform/network/BlobRegistry.h (201692 => 201693)


--- trunk/Source/WebCore/platform/network/BlobRegistry.h	2016-06-05 00:59:40 UTC (rev 201692)
+++ trunk/Source/WebCore/platform/network/BlobRegistry.h	2016-06-05 03:46:42 UTC (rev 201693)
@@ -33,6 +33,7 @@
 
 #include <functional>
 #include <wtf/Forward.h>
+#include <wtf/NoncopyableFunction.h>
 #include <wtf/Vector.h>
 
 namespace WebCore {
@@ -67,7 +68,7 @@
 
     virtual unsigned long long blobSize(const URL&) = 0;
 
-    virtual void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, std::function<void (const Vector<String>& filePaths)> completionHandler) = 0;
+    virtual void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, NoncopyableFunction<void (const Vector<String>& filePaths)>&& completionHandler) = 0;
 
     virtual bool isBlobRegistryImpl() const { return false; }
 

Modified: trunk/Source/WebCore/platform/network/BlobRegistryImpl.cpp (201692 => 201693)


--- trunk/Source/WebCore/platform/network/BlobRegistryImpl.cpp	2016-06-05 00:59:40 UTC (rev 201692)
+++ trunk/Source/WebCore/platform/network/BlobRegistryImpl.cpp	2016-06-05 03:46:42 UTC (rev 201693)
@@ -256,7 +256,7 @@
     Vector<std::pair<String, ThreadSafeDataBuffer>> filePathsOrDataBuffers;
 };
 
-void BlobRegistryImpl::writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, std::function<void (const Vector<String>& filePaths)> completionHandler)
+void BlobRegistryImpl::writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, NoncopyableFunction<void (const Vector<String>& filePaths)>&& completionHandler)
 {
     Vector<BlobForFileWriting> blobsForWriting;
     for (auto& url : blobURLs) {
@@ -287,47 +287,45 @@
     blobUtilityQueue().dispatch([blobsForWriting = WTFMove(blobsForWriting), completionHandler = WTFMove(completionHandler)]() mutable {
         Vector<String> filePaths;
 
-        ScopeGuard completionCaller([completionHandler]() mutable {
-            callOnMainThread([completionHandler = WTFMove(completionHandler)]() {
-                Vector<String> filePaths;
-                completionHandler(filePaths);
-            });
-        });
+        auto performWriting = [blobsForWriting = WTFMove(blobsForWriting), &filePaths]() {
+            for (auto& blob : blobsForWriting) {
+                PlatformFileHandle file;
+                String tempFilePath = openTemporaryFile(ASCIILiteral("Blob"), file);
 
-        for (auto& blob : blobsForWriting) {
-            PlatformFileHandle file;
-            String tempFilePath = openTemporaryFile(ASCIILiteral("Blob"), file);
+                ScopeGuard fileCloser([file]() mutable {
+                    closeFile(file);
+                });
+                
+                if (tempFilePath.isEmpty() || !isHandleValid(file)) {
+                    LOG_ERROR("Failed to open temporary file for writing a Blob to IndexedDB");
+                    return false;
+                }
 
-            ScopeGuard fileCloser([file]() {
-                PlatformFileHandle handle = file;
-                closeFile(handle);
-            });
-            
-            if (tempFilePath.isEmpty() || !isHandleValid(file)) {
-                LOG_ERROR("Failed to open temporary file for writing a Blob to IndexedDB");
-                return;
-            }
-
-            for (auto& part : blob.filePathsOrDataBuffers) {
-                if (part.second.data()) {
-                    int length = part.second.data()->size();
-                    if (writeToFile(file, reinterpret_cast<const char*>(part.second.data()->data()), length) != length) {
-                        LOG_ERROR("Failed writing a Blob to temporary file for storage in IndexedDB");
-                        return;
+                for (auto& part : blob.filePathsOrDataBuffers) {
+                    if (part.second.data()) {
+                        int length = part.second.data()->size();
+                        if (writeToFile(file, reinterpret_cast<const char*>(part.second.data()->data()), length) != length) {
+                            LOG_ERROR("Failed writing a Blob to temporary file for storage in IndexedDB");
+                            return false;
+                        }
+                    } else {
+                        ASSERT(!part.first.isEmpty());
+                        if (!appendFileContentsToFileHandle(part.first, file)) {
+                            LOG_ERROR("Failed copying File contents to a Blob temporary file for storage in IndexedDB (%s to %s)", part.first.utf8().data(), tempFilePath.utf8().data());
+                            return false;
+                        }
                     }
-                } else {
-                    ASSERT(!part.first.isEmpty());
-                    if (!appendFileContentsToFileHandle(part.first, file)) {
-                        LOG_ERROR("Failed copying File contents to a Blob temporary file for storage in IndexedDB (%s to %s)", part.first.utf8().data(), tempFilePath.utf8().data());
-                        return;
-                    }
                 }
+
+                filePaths.append(tempFilePath.isolatedCopy());
             }
 
-            filePaths.append(tempFilePath.isolatedCopy());
-        }
+            return true;
+        };
 
-        completionCaller.disable();
+        if (!performWriting())
+            filePaths.clear();
+
         callOnMainThread([completionHandler = WTFMove(completionHandler), filePaths = WTFMove(filePaths)]() {
             completionHandler(filePaths);
         });

Modified: trunk/Source/WebCore/platform/network/BlobRegistryImpl.h (201692 => 201693)


--- trunk/Source/WebCore/platform/network/BlobRegistryImpl.h	2016-06-05 00:59:40 UTC (rev 201692)
+++ trunk/Source/WebCore/platform/network/BlobRegistryImpl.h	2016-06-05 03:46:42 UTC (rev 201693)
@@ -68,7 +68,7 @@
 
     unsigned long long blobSize(const URL&) override;
 
-    void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, std::function<void (const Vector<String>& filePaths)> completionHandler) override;
+    void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, NoncopyableFunction<void (const Vector<String>& filePaths)>&& completionHandler) override;
 
     HashMap<String, RefPtr<BlobData>> m_blobs;
 };
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to