Diff
Modified: trunk/Source/WebCore/ChangeLog (199229 => 199230)
--- trunk/Source/WebCore/ChangeLog 2016-04-08 16:36:01 UTC (rev 199229)
+++ trunk/Source/WebCore/ChangeLog 2016-04-08 16:57:29 UTC (rev 199230)
@@ -1,3 +1,67 @@
+2016-04-08 Brady Eidson <[email protected]>
+
+ Modern IDB (Blob support): Write blobs to temporary files and move them to the correct location when storing them.
+ https://bugs.webkit.org/show_bug.cgi?id=156321
+
+ Reviewed by Alex Christensen, Andy Estes, and Darin Adler.
+
+ No new tests (No testable change in behavior yet, current tests pass).
+
+ When asked to store a Blob (including Files) in IndexedDB, the Blob is written out to a temporary file.
+
+ Then when the putOrAdd request is received by IDBServer it includes a list of blobURLs and their mappings
+ to temporary files.
+
+ Finally, as part of storing the Blob value in the database, those temporary files are moved in to place
+ under the IndexedDB directory for storage and later retrieval.
+
+ * Modules/indexeddb/IDBValue.cpp:
+ (WebCore::IDBValue::IDBValue):
+
+ * Modules/indexeddb/server/IDBBackingStore.h:
+ (WebCore::IDBServer::IDBBackingStoreTemporaryFileHandler::~IDBBackingStoreTemporaryFileHandler):
+
+ * Modules/indexeddb/server/IDBServer.cpp:
+ (WebCore::IDBServer::IDBServer::create):
+ (WebCore::IDBServer::IDBServer::IDBServer):
+ (WebCore::IDBServer::IDBServer::createBackingStore):
+ * Modules/indexeddb/server/IDBServer.h:
+
+ * Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
+ (WebCore::IDBServer::blobRecordsTableSchema):
+ (WebCore::IDBServer::blobRecordsTableSchemaAlternate):
+ (WebCore::IDBServer::blobFilesTableSchema):
+ (WebCore::IDBServer::blobFilesTableSchemaAlternate):
+ (WebCore::IDBServer::SQLiteIDBBackingStore::SQLiteIDBBackingStore):
+ (WebCore::IDBServer::SQLiteIDBBackingStore::ensureValidBlobTables):
+ (WebCore::IDBServer::SQLiteIDBBackingStore::getOrEstablishDatabaseInfo):
+ (WebCore::IDBServer::SQLiteIDBBackingStore::addRecord):
+ * Modules/indexeddb/server/SQLiteIDBBackingStore.h:
+ (WebCore::IDBServer::SQLiteIDBBackingStore::temporaryFileHandler):
+
+ * Modules/indexeddb/server/SQLiteIDBTransaction.cpp:
+ (WebCore::IDBServer::SQLiteIDBTransaction::commit):
+ (WebCore::IDBServer::SQLiteIDBTransaction::moveBlobFilesIfNecessary):
+ (WebCore::IDBServer::SQLiteIDBTransaction::abort):
+ (WebCore::IDBServer::SQLiteIDBTransaction::reset):
+ (WebCore::IDBServer::SQLiteIDBTransaction::addBlobFile):
+ * Modules/indexeddb/server/SQLiteIDBTransaction.h:
+
+ * Modules/indexeddb/shared/InProcessIDBServer.cpp:
+ (WebCore::InProcessIDBServer::InProcessIDBServer):
+ (WebCore::InProcessIDBServer::accessToTemporaryFileComplete):
+ * Modules/indexeddb/shared/InProcessIDBServer.h:
+
+ * bindings/js/SerializedScriptValue.cpp:
+ (WebCore::SerializedScriptValue::blobURLsIsolatedCopy):
+ * bindings/js/SerializedScriptValue.h:
+
+ * platform/FileSystem.h:
+ * platform/gtk/FileSystemGtk.cpp:
+ (WebCore::hardLinkOrCopyFile):
+ * platform/posix/FileSystemPOSIX.cpp:
+ (WebCore::hardLinkOrCopyFile):
+
2016-04-08 Joanmarie Diggs <[email protected]>
AX: [ATK] Crash getting text under element in CSS table
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBValue.cpp (199229 => 199230)
--- trunk/Source/WebCore/Modules/indexeddb/IDBValue.cpp 2016-04-08 16:36:01 UTC (rev 199229)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBValue.cpp 2016-04-08 16:57:29 UTC (rev 199230)
@@ -38,6 +38,7 @@
IDBValue::IDBValue(const SerializedScriptValue& scriptValue)
: m_data(ThreadSafeDataBuffer::copyVector(scriptValue.data()))
+ , m_blobURLs(scriptValue.blobURLsIsolatedCopy())
{
}
Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBBackingStore.h (199229 => 199230)
--- trunk/Source/WebCore/Modules/indexeddb/server/IDBBackingStore.h 2016-04-08 16:36:01 UTC (rev 199229)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBBackingStore.h 2016-04-08 16:57:29 UTC (rev 199230)
@@ -50,6 +50,13 @@
namespace IDBServer {
+class IDBBackingStoreTemporaryFileHandler {
+public:
+ virtual ~IDBBackingStoreTemporaryFileHandler() { }
+ virtual void prepareForAccessToTemporaryFile(const String& path) = 0;
+ virtual void accessToTemporaryFileComplete(const String& path) = 0;
+};
+
class IDBBackingStore {
public:
virtual ~IDBBackingStore() { }
Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp (199229 => 199230)
--- trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp 2016-04-08 16:36:01 UTC (rev 199229)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp 2016-04-08 16:57:29 UTC (rev 199230)
@@ -39,24 +39,26 @@
namespace WebCore {
namespace IDBServer {
-Ref<IDBServer> IDBServer::create()
+Ref<IDBServer> IDBServer::create(IDBBackingStoreTemporaryFileHandler& fileHandler)
{
- return adoptRef(*new IDBServer());
+ return adoptRef(*new IDBServer(fileHandler));
}
-Ref<IDBServer> IDBServer::create(const String& databaseDirectoryPath)
+Ref<IDBServer> IDBServer::create(const String& databaseDirectoryPath, IDBBackingStoreTemporaryFileHandler& fileHandler)
{
- return adoptRef(*new IDBServer(databaseDirectoryPath));
+ return adoptRef(*new IDBServer(databaseDirectoryPath, fileHandler));
}
-IDBServer::IDBServer()
+IDBServer::IDBServer(IDBBackingStoreTemporaryFileHandler& fileHandler)
+ : m_backingStoreTemporaryFileHandler(fileHandler)
{
Locker<Lock> locker(m_databaseThreadCreationLock);
m_threadID = createThread(IDBServer::databaseThreadEntry, this, "IndexedDatabase Server");
}
-IDBServer::IDBServer(const String& databaseDirectoryPath)
+IDBServer::IDBServer(const String& databaseDirectoryPath, IDBBackingStoreTemporaryFileHandler& fileHandler)
: m_databaseDirectoryPath(databaseDirectoryPath)
+ , m_backingStoreTemporaryFileHandler(fileHandler)
{
LOG(IndexedDB, "IDBServer created at path %s", databaseDirectoryPath.utf8().data());
@@ -120,7 +122,7 @@
if (m_databaseDirectoryPath.isEmpty())
return MemoryIDBBackingStore::create(identifier);
- return std::make_unique<SQLiteIDBBackingStore>(identifier, m_databaseDirectoryPath);
+ return std::make_unique<SQLiteIDBBackingStore>(identifier, m_databaseDirectoryPath, m_backingStoreTemporaryFileHandler);
}
void IDBServer::openDatabase(const IDBRequestData& requestData)
Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.h (199229 => 199230)
--- trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.h 2016-04-08 16:36:01 UTC (rev 199229)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.h 2016-04-08 16:57:29 UTC (rev 199230)
@@ -49,10 +49,12 @@
namespace IDBServer {
+class IDBBackingStoreTemporaryFileHandler;
+
class IDBServer : public RefCounted<IDBServer> {
public:
- static Ref<IDBServer> create();
- WEBCORE_EXPORT static Ref<IDBServer> create(const String& databaseDirectoryPath);
+ static Ref<IDBServer> create(IDBBackingStoreTemporaryFileHandler&);
+ WEBCORE_EXPORT static Ref<IDBServer> create(const String& databaseDirectoryPath, IDBBackingStoreTemporaryFileHandler&);
WEBCORE_EXPORT void registerConnection(IDBConnectionToClient&);
WEBCORE_EXPORT void unregisterConnection(IDBConnectionToClient&);
@@ -93,8 +95,8 @@
std::unique_ptr<IDBBackingStore> createBackingStore(const IDBDatabaseIdentifier&);
private:
- IDBServer();
- IDBServer(const String& databaseDirectoryPath);
+ IDBServer(IDBBackingStoreTemporaryFileHandler&);
+ IDBServer(const String& databaseDirectoryPath, IDBBackingStoreTemporaryFileHandler&);
UniqueIDBDatabase& getOrCreateUniqueIDBDatabase(const IDBDatabaseIdentifier&);
@@ -117,6 +119,7 @@
HashMap<IDBResourceIdentifier, UniqueIDBDatabaseTransaction*> m_transactions;
String m_databaseDirectoryPath;
+ IDBBackingStoreTemporaryFileHandler& m_backingStoreTemporaryFileHandler;
};
} // namespace IDBServer
Modified: trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp (199229 => 199230)
--- trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp 2016-04-08 16:36:01 UTC (rev 199229)
+++ trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp 2016-04-08 16:57:29 UTC (rev 199230)
@@ -160,9 +160,43 @@
return v2IndexRecordsTableSchemaString;
}
+static const String blobRecordsTableSchema(const String& tableName)
+{
+ return makeString("CREATE TABLE ", tableName, " (objectStoreRow INTEGER NOT NULL ON CONFLICT FAIL, blobURL TEXT NOT NULL ON CONFLICT FAIL)");
+}
-SQLiteIDBBackingStore::SQLiteIDBBackingStore(const IDBDatabaseIdentifier& identifier, const String& databaseRootDirectory)
+static const String& blobRecordsTableSchema()
+{
+ static NeverDestroyed<String> blobRecordsTableSchemaString(blobRecordsTableSchema("BlobRecords"));
+ return blobRecordsTableSchemaString;
+}
+
+static const String& blobRecordsTableSchemaAlternate()
+{
+ static NeverDestroyed<String> blobRecordsTableSchemaString(blobRecordsTableSchema("\"BlobRecords\""));
+ return blobRecordsTableSchemaString;
+}
+
+static const String blobFilesTableSchema(const String& tableName)
+{
+ return makeString("CREATE TABLE ", tableName, " (blobURL TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT FAIL, fileName TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT FAIL)");
+}
+
+static const String& blobFilesTableSchema()
+{
+ static NeverDestroyed<String> blobFilesTableSchemaString(blobFilesTableSchema("BlobFiles"));
+ return blobFilesTableSchemaString;
+}
+
+static const String& blobFilesTableSchemaAlternate()
+{
+ static NeverDestroyed<String> blobFilesTableSchemaString(blobFilesTableSchema("\"BlobFiles\""));
+ return blobFilesTableSchemaString;
+}
+
+SQLiteIDBBackingStore::SQLiteIDBBackingStore(const IDBDatabaseIdentifier& identifier, const String& databaseRootDirectory, IDBBackingStoreTemporaryFileHandler& fileHandler)
: m_identifier(identifier)
+ , m_temporaryFileHandler(fileHandler)
{
m_absoluteDatabaseDirectory = identifier.databaseDirectoryRelativeToRoot(databaseRootDirectory);
}
@@ -275,6 +309,78 @@
return true;
}
+bool SQLiteIDBBackingStore::ensureValidBlobTables()
+{
+ ASSERT(m_sqliteDB);
+ ASSERT(m_sqliteDB->isOpen());
+
+ String currentSchema;
+ {
+ // Fetch the schema for an existing blob record table.
+ SQLiteStatement statement(*m_sqliteDB, "SELECT type, sql FROM sqlite_master WHERE tbl_name='BlobRecords'");
+ if (statement.prepare() != SQLITE_OK) {
+ LOG_ERROR("Unable to prepare statement to fetch schema for the BlobRecords table.");
+ return false;
+ }
+
+ int sqliteResult = statement.step();
+
+ // If there is no BlobRecords table at all, create it..
+ if (sqliteResult == SQLITE_DONE) {
+ if (!m_sqliteDB->executeCommand(blobRecordsTableSchema())) {
+ LOG_ERROR("Could not create BlobRecords table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+ return false;
+ }
+
+ currentSchema = blobRecordsTableSchema();
+ } else if (sqliteResult != SQLITE_ROW) {
+ LOG_ERROR("Error executing statement to fetch schema for the BlobRecords table.");
+ return false;
+ } else
+ currentSchema = statement.getColumnText(1);
+ }
+
+ if (currentSchema != blobRecordsTableSchema() && currentSchema != blobRecordsTableSchemaAlternate()) {
+ LOG_ERROR("Invalid BlobRecords table schema found");
+ return false;
+ }
+
+ {
+ // Fetch the schema for an existing blob file table.
+ SQLiteStatement statement(*m_sqliteDB, "SELECT type, sql FROM sqlite_master WHERE tbl_name='BlobFiles'");
+ if (statement.prepare() != SQLITE_OK) {
+ LOG_ERROR("Unable to prepare statement to fetch schema for the BlobFiles table.");
+ return false;
+ }
+
+ int sqliteResult = statement.step();
+
+ // If there is no BlobFiles table at all, create it and then bail.
+ if (sqliteResult == SQLITE_DONE) {
+ if (!m_sqliteDB->executeCommand(blobFilesTableSchema())) {
+ LOG_ERROR("Could not create BlobFiles table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+ return false;
+ }
+
+ return true;
+ }
+
+ if (sqliteResult != SQLITE_ROW) {
+ LOG_ERROR("Error executing statement to fetch schema for the BlobFiles table.");
+ return false;
+ }
+
+ currentSchema = statement.getColumnText(1);
+ }
+
+ if (currentSchema != blobFilesTableSchema() && currentSchema != blobFilesTableSchemaAlternate()) {
+ LOG_ERROR("Invalid BlobFiles table schema found");
+ return false;
+ }
+
+ return true;
+}
+
bool SQLiteIDBBackingStore::ensureValidRecordsTable()
{
ASSERT(m_sqliteDB);
@@ -612,6 +718,12 @@
return { IDBDatabaseException::UnknownError, ASCIILiteral("Error creating or migrating Index Records table in database") };
}
+ if (!ensureValidBlobTables()) {
+ LOG_ERROR("Error creating or confirming Blob Records tables in database");
+ m_sqliteDB = nullptr;
+ return { IDBDatabaseException::UnknownError, ASCIILiteral("Error creating or confirming Blob Records tables in database") };
+ }
+
auto databaseInfo = extractExistingDatabaseInfo();
if (!databaseInfo)
databaseInfo = createAndPopulateInitialDatabaseInfo();
@@ -1300,13 +1412,14 @@
return error;
}
-IDBError SQLiteIDBBackingStore::addRecord(const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo& objectStoreInfo, const IDBKeyData& keyData, const ThreadSafeDataBuffer& value, const Vector<String>&, const Vector<String>&)
+IDBError SQLiteIDBBackingStore::addRecord(const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo& objectStoreInfo, const IDBKeyData& keyData, const ThreadSafeDataBuffer& value, const Vector<String>& blobURLs, const Vector<String>& blobFiles)
{
LOG(IndexedDB, "SQLiteIDBBackingStore::addRecord - key %s, object store %" PRIu64, keyData.loggingString().utf8().data(), objectStoreInfo.identifier());
ASSERT(m_sqliteDB);
ASSERT(m_sqliteDB->isOpen());
ASSERT(value.data());
+ ASSERT(blobURLs.size() == blobFiles.size());
auto* transaction = m_transactions.get(transactionIdentifier);
if (!transaction || !transaction->inProgress()) {
@@ -1323,6 +1436,8 @@
LOG_ERROR("Unable to serialize IDBKey to be stored in an object store");
return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize IDBKey to be stored in an object store") };
}
+
+ int64_t recordID = 0;
{
SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO Records VALUES (?, CAST(? AS TEXT), ?, NULL);"));
if (sql.prepare() != SQLITE_OK
@@ -1333,6 +1448,8 @@
LOG_ERROR("Could not put record for object store %" PRIi64 " in Records table (%i) - %s", objectStoreInfo.identifier(), m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to store record in object store") };
}
+
+ recordID = m_sqliteDB->lastInsertRowID();
}
auto error = updateAllIndexesForAddRecord(objectStoreInfo, keyData, value);
@@ -1348,6 +1465,55 @@
}
}
+ for (size_t i = 0; i < blobURLs.size(); ++i) {
+ auto& url = ""
+ {
+ SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO BlobRecords VALUES (?, ?);"));
+ if (sql.prepare() != SQLITE_OK
+ || sql.bindInt64(1, recordID) != SQLITE_OK
+ || sql.bindText(2, url) != SQLITE_OK
+ || sql.step() != SQLITE_DONE) {
+ LOG_ERROR("Unable to record Blob record in database");
+ return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to record Blob record in database") };
+ }
+ }
+ int64_t potentialFileNameInteger = m_sqliteDB->lastInsertRowID();
+
+ // If we already have a file for this blobURL, nothing left to do.
+ {
+ SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT fileName FROM BlobFiles WHERE blobURL = ?;"));
+ if (sql.prepare() != SQLITE_OK
+ || sql.bindText(1, url) != SQLITE_OK) {
+ LOG_ERROR("Unable to examine Blob filenames in database");
+ return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to examine Blob filenames in database") };
+ }
+
+ int result = sql.step();
+ if (result != SQLITE_ROW && result != SQLITE_DONE) {
+ LOG_ERROR("Unable to examine Blob filenames in database");
+ return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to examine Blob filenames in database") };
+ }
+
+ if (result == SQLITE_ROW)
+ continue;
+ }
+
+ // We don't already have a file for this blobURL, so commit our file as a unique filename
+ String storedFilename = String::format("%" PRId64 ".blob", potentialFileNameInteger);
+ {
+ SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO BlobFiles VALUES (?, ?);"));
+ if (sql.prepare() != SQLITE_OK
+ || sql.bindText(1, url) != SQLITE_OK
+ || sql.bindText(2, storedFilename) != SQLITE_OK
+ || sql.step() != SQLITE_DONE) {
+ LOG_ERROR("Unable to record Blob file record in database");
+ return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to record Blob file record in database") };
+ }
+ }
+
+ transaction->addBlobFile(blobFiles[i], storedFilename);
+ }
+
transaction->notifyCursorsOfChanges(objectStoreInfo.identifier());
return error;
Modified: trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h (199229 => 199230)
--- trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h 2016-04-08 16:36:01 UTC (rev 199229)
+++ trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h 2016-04-08 16:57:29 UTC (rev 199230)
@@ -47,7 +47,7 @@
class SQLiteIDBBackingStore : public IDBBackingStore {
public:
- SQLiteIDBBackingStore(const IDBDatabaseIdentifier&, const String& databaseRootDirectory);
+ SQLiteIDBBackingStore(const IDBDatabaseIdentifier&, const String& databaseRootDirectory, IDBBackingStoreTemporaryFileHandler&);
~SQLiteIDBBackingStore() final;
@@ -81,13 +81,17 @@
void unregisterCursor(SQLiteIDBCursor&);
+ String fullDatabaseDirectory() const;
+
+ IDBBackingStoreTemporaryFileHandler& temporaryFileHandler() const { return m_temporaryFileHandler; }
+
private:
String filenameForDatabaseName() const;
- String fullDatabaseDirectory() const;
String fullDatabasePath() const;
bool ensureValidRecordsTable();
bool ensureValidIndexRecordsTable();
+ bool ensureValidBlobTables();
std::unique_ptr<IDBDatabaseInfo> createAndPopulateInitialDatabaseInfo();
std::unique_ptr<IDBDatabaseInfo> extractExistingDatabaseInfo();
@@ -118,6 +122,8 @@
RefPtr<JSC::VM> m_vm;
JSC::Strong<JSC::JSGlobalObject> m_globalObject;
+
+ IDBBackingStoreTemporaryFileHandler& m_temporaryFileHandler;
};
} // namespace IDBServer
Modified: trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBTransaction.cpp (199229 => 199230)
--- trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBTransaction.cpp 2016-04-08 16:36:01 UTC (rev 199229)
+++ trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBTransaction.cpp 2016-04-08 16:57:29 UTC (rev 199230)
@@ -27,6 +27,7 @@
#if ENABLE(INDEXED_DATABASE)
+#include "FileSystem.h"
#include "IDBCursorInfo.h"
#include "IndexedDB.h"
#include "SQLiteIDBBackingStore.h"
@@ -75,12 +76,36 @@
if (m_sqliteTransaction->inProgress())
return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to commit SQLite transaction in database backend") };
+ moveBlobFilesIfNecessary();
+
reset();
return { };
}
+void SQLiteIDBTransaction::moveBlobFilesIfNecessary()
+{
+ String databaseDirectory = m_backingStore.fullDatabaseDirectory();
+ for (auto& entry : m_blobTemporaryAndStoredFilenames) {
+ m_backingStore.temporaryFileHandler().prepareForAccessToTemporaryFile(entry.first);
+
+ if (!hardLinkOrCopyFile(entry.first, pathByAppendingComponent(databaseDirectory, entry.second)))
+ LOG_ERROR("Failed to link/copy temporary blob file '%s' to location '%s'", entry.first.utf8().data(), pathByAppendingComponent(databaseDirectory, entry.second).utf8().data());
+
+ m_backingStore.temporaryFileHandler().accessToTemporaryFileComplete(entry.first);
+ }
+
+ m_blobTemporaryAndStoredFilenames.clear();
+}
+
IDBError SQLiteIDBTransaction::abort()
{
+ for (auto& entry : m_blobTemporaryAndStoredFilenames) {
+ m_backingStore.temporaryFileHandler().prepareForAccessToTemporaryFile(entry.first);
+ m_backingStore.temporaryFileHandler().accessToTemporaryFileComplete(entry.first);
+ }
+
+ m_blobTemporaryAndStoredFilenames.clear();
+
if (!m_sqliteTransaction || !m_sqliteTransaction->inProgress())
return { IDBDatabaseException::UnknownError, ASCIILiteral("No SQLite transaction in progress to abort") };
@@ -97,6 +122,7 @@
{
m_sqliteTransaction = nullptr;
clearCursors();
+ ASSERT(m_blobTemporaryAndStoredFilenames.isEmpty());
}
std::unique_ptr<SQLiteIDBCursor> SQLiteIDBTransaction::maybeOpenBackingStoreCursor(uint64_t objectStoreID, uint64_t indexID, const IDBKeyRangeData& range)
@@ -171,6 +197,11 @@
return m_sqliteTransaction && m_sqliteTransaction->inProgress();
}
+void SQLiteIDBTransaction::addBlobFile(const String& temporaryPath, const String& storedFilename)
+{
+ m_blobTemporaryAndStoredFilenames.append({ temporaryPath, storedFilename });
+}
+
} // namespace IDBServer
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBTransaction.h (199229 => 199230)
--- trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBTransaction.h 2016-04-08 16:36:01 UTC (rev 199229)
+++ trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBTransaction.h 2016-04-08 16:57:29 UTC (rev 199230)
@@ -71,16 +71,21 @@
SQLiteTransaction* sqliteTransaction() const { return m_sqliteTransaction.get(); }
+ void addBlobFile(const String& temporaryPath, const String& storedFilename);
+
private:
void clearCursors();
void reset();
+ void moveBlobFilesIfNecessary();
+
IDBTransactionInfo m_info;
SQLiteIDBBackingStore& m_backingStore;
std::unique_ptr<SQLiteTransaction> m_sqliteTransaction;
HashMap<IDBResourceIdentifier, std::unique_ptr<SQLiteIDBCursor>> m_cursors;
HashSet<SQLiteIDBCursor*> m_backingStoreCursors;
+ Vector<std::pair<String, String>> m_blobTemporaryAndStoredFilenames;
};
} // namespace IDBServer
Modified: trunk/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.cpp (199229 => 199230)
--- trunk/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.cpp 2016-04-08 16:36:01 UTC (rev 199229)
+++ trunk/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.cpp 2016-04-08 16:57:29 UTC (rev 199230)
@@ -28,6 +28,7 @@
#if ENABLE(INDEXED_DATABASE)
+#include "FileSystem.h"
#include "IDBConnectionToClient.h"
#include "IDBConnectionToServer.h"
#include "IDBCursorInfo.h"
@@ -56,7 +57,7 @@
}
InProcessIDBServer::InProcessIDBServer()
- : m_server(IDBServer::IDBServer::create())
+ : m_server(IDBServer::IDBServer::create(*this))
{
relaxAdoptionRequirement();
m_connectionToServer = IDBClient::IDBConnectionToServer::create(*this);
@@ -64,7 +65,7 @@
}
InProcessIDBServer::InProcessIDBServer(const String& databaseDirectoryPath)
- : m_server(IDBServer::IDBServer::create(databaseDirectoryPath))
+ : m_server(IDBServer::IDBServer::create(databaseDirectoryPath, *this))
{
relaxAdoptionRequirement();
m_connectionToServer = IDBClient::IDBConnectionToServer::create(*this);
@@ -400,6 +401,11 @@
});
}
+void InProcessIDBServer::accessToTemporaryFileComplete(const String& path)
+{
+ deleteFile(path);
+}
+
} // namespace WebCore
#endif // ENABLE(INDEXED_DATABASE)
Modified: trunk/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.h (199229 => 199230)
--- trunk/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.h 2016-04-08 16:36:01 UTC (rev 199229)
+++ trunk/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.h 2016-04-08 16:57:29 UTC (rev 199230)
@@ -46,7 +46,7 @@
class IDBServer;
}
-class InProcessIDBServer final : public IDBClient::IDBConnectionToServerDelegate, public IDBServer::IDBConnectionToClientDelegate, public RefCounted<InProcessIDBServer> {
+class InProcessIDBServer final : public IDBClient::IDBConnectionToServerDelegate, public IDBServer::IDBConnectionToClientDelegate, public RefCounted<InProcessIDBServer>, public IDBServer::IDBBackingStoreTemporaryFileHandler {
public:
WEBCORE_EXPORT static Ref<InProcessIDBServer> create();
WEBCORE_EXPORT static Ref<InProcessIDBServer> create(const String& databaseDirectoryPath);
@@ -100,6 +100,9 @@
void ref() override { RefCounted<InProcessIDBServer>::ref(); }
void deref() override { RefCounted<InProcessIDBServer>::deref(); }
+ void prepareForAccessToTemporaryFile(const String&) override { }
+ void accessToTemporaryFileComplete(const String& path) override;
+
private:
InProcessIDBServer();
InProcessIDBServer(const String& databaseDirectoryPath);
Modified: trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp (199229 => 199230)
--- trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp 2016-04-08 16:36:01 UTC (rev 199229)
+++ trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp 2016-04-08 16:57:29 UTC (rev 199230)
@@ -2748,6 +2748,16 @@
}
#if ENABLE(INDEXED_DATABASE)
+Vector<String> SerializedScriptValue::blobURLsIsolatedCopy() const
+{
+ Vector<String> result;
+ result.reserveInitialCapacity(m_blobURLs.size());
+ for (auto& url : m_blobURLs)
+ result.uncheckedAppend(url.isolatedCopy());
+
+ return result;
+}
+
void SerializedScriptValue::writeBlobsToDiskForIndexedDB(std::function<void (const IDBValue&)> completionHandler)
{
ASSERT(isMainThread());
@@ -2769,6 +2779,6 @@
completionHandler({ *this, m_blobURLs, blobFilePaths });
});
}
-#endif
+#endif // ENABLE(INDEXED_DATABASE)
} // namespace WebCore
Modified: trunk/Source/WebCore/bindings/js/SerializedScriptValue.h (199229 => 199230)
--- trunk/Source/WebCore/bindings/js/SerializedScriptValue.h 2016-04-08 16:36:01 UTC (rev 199229)
+++ trunk/Source/WebCore/bindings/js/SerializedScriptValue.h 2016-04-08 16:57:29 UTC (rev 199230)
@@ -84,9 +84,11 @@
const Vector<uint8_t>& data() const { return m_data; }
bool hasBlobURLs() const { return !m_blobURLs.isEmpty(); }
+
#if ENABLE(INDEXED_DATABASE)
+ Vector<String> blobURLsIsolatedCopy() const;
void writeBlobsToDiskForIndexedDB(std::function<void (const IDBValue&)> completionHandler);
-#endif
+#endif // ENABLE(INDEXED_DATABASE)
static Ref<SerializedScriptValue> createFromWireBytes(Vector<uint8_t>&& data)
{
Modified: trunk/Source/WebCore/platform/FileSystem.h (199229 => 199230)
--- trunk/Source/WebCore/platform/FileSystem.h 2016-04-08 16:36:01 UTC (rev 199229)
+++ trunk/Source/WebCore/platform/FileSystem.h 2016-04-08 16:57:29 UTC (rev 199230)
@@ -181,6 +181,9 @@
// Returns true if the write was successful, false if it was not.
bool appendFileContentsToFileHandle(const String& path, PlatformFileHandle&);
+// Hard links a file if possible, copies it if not.
+bool hardLinkOrCopyFile(const String& source, const String& destination);
+
#if USE(FILE_LOCK)
bool lockFile(PlatformFileHandle, FileLockMode);
bool unlockFile(PlatformFileHandle);
Modified: trunk/Source/WebCore/platform/gtk/FileSystemGtk.cpp (199229 => 199230)
--- trunk/Source/WebCore/platform/gtk/FileSystemGtk.cpp 2016-04-08 16:36:01 UTC (rev 199229)
+++ trunk/Source/WebCore/platform/gtk/FileSystemGtk.cpp 2016-04-08 16:57:29 UTC (rev 199230)
@@ -364,4 +364,11 @@
return g_module_close(module);
#endif
}
+
+bool hardLinkOrCopyFile(const String&, const String&)
+{
+ // FIXME: Implement
+ return false;
}
+
+}
Modified: trunk/Source/WebCore/platform/posix/FileSystemPOSIX.cpp (199229 => 199230)
--- trunk/Source/WebCore/platform/posix/FileSystemPOSIX.cpp 2016-04-08 16:36:01 UTC (rev 199229)
+++ trunk/Source/WebCore/platform/posix/FileSystemPOSIX.cpp 2016-04-08 16:57:29 UTC (rev 199230)
@@ -346,4 +346,35 @@
}
#endif
+bool hardLinkOrCopyFile(const String& source, const String& destination)
+{
+ if (source.isEmpty() || destination.isEmpty())
+ return false;
+
+ CString fsSource = fileSystemRepresentation(source);
+ if (!fsSource.data())
+ return false;
+
+ CString fsDestination = fileSystemRepresentation(destination);
+ if (!fsDestination.data())
+ return false;
+
+ if (!link(fsSource.data(), fsDestination.data()))
+ return true;
+
+ // Hard link failed. Perform a copy instead.
+ auto handle = open(fsDestination.data(), O_WRONLY | O_CREAT | O_EXCL);
+ if (handle == -1)
+ return false;
+
+ bool appendResult = appendFileContentsToFileHandle(source, handle);
+ close(handle);
+
+ // If the copy failed, delete the unusable file.
+ if (!appendResult)
+ unlink(fsDestination.data());
+
+ return appendResult;
+}
+
} // namespace WebCore
Modified: trunk/Source/WebKit2/ChangeLog (199229 => 199230)
--- trunk/Source/WebKit2/ChangeLog 2016-04-08 16:36:01 UTC (rev 199229)
+++ trunk/Source/WebKit2/ChangeLog 2016-04-08 16:57:29 UTC (rev 199230)
@@ -1,3 +1,40 @@
+2016-04-08 Brady Eidson <[email protected]>
+
+ Modern IDB (Blob support): Write blobs to temporary files and move them to the correct location when storing them.
+ https://bugs.webkit.org/show_bug.cgi?id=156321
+
+ Reviewed by Alex Christensen, Andy Estes, and Darin Adler.
+
+ The NetworkProcess writes a blob to a temporary file, then tells the UIProcess to grant the DatabaseProcess
+ a Sandbox Extension to that path.
+
+ It then tells the WebProcess the paths for the temporary files, which then tells the DatabaseProcess to store
+ the contents of those files as blob references in the database.
+
+ Since the UIProcess had already granted it a Sandbox Extension, it is able to do so.
+
+ * DatabaseProcess/DatabaseProcess.cpp:
+ (WebKit::DatabaseProcess::idbServer):
+ (WebKit::DatabaseProcess::grantSandboxExtensionsForBlobs):
+ (WebKit::DatabaseProcess::prepareForAccessToTemporaryFile):
+ (WebKit::DatabaseProcess::accessToTemporaryFileComplete):
+ * DatabaseProcess/DatabaseProcess.h:
+ * DatabaseProcess/DatabaseProcess.messages.in:
+
+ * NetworkProcess/NetworkConnectionToWebProcess.cpp:
+ (WebKit::NetworkConnectionToWebProcess::writeBlobsToTemporaryFiles):
+
+ * NetworkProcess/NetworkProcess.cpp:
+ (WebKit::NetworkProcess::grantSandboxExtensionsToDatabaseProcessForBlobs):
+ (WebKit::NetworkProcess::didGrantSandboxExtensionsToDatabaseProcessForBlobs):
+ * NetworkProcess/NetworkProcess.h:
+ * NetworkProcess/NetworkProcess.messages.in:
+
+ * UIProcess/Network/NetworkProcessProxy.cpp:
+ (WebKit::NetworkProcessProxy::grantSandboxExtensionsToDatabaseProcessForBlobs):
+ * UIProcess/Network/NetworkProcessProxy.h:
+ * UIProcess/Network/NetworkProcessProxy.messages.in:
+
2016-04-07 Joseph Pecoraro <[email protected]>
Remove ENABLE(ENABLE_ES6_CLASS_SYNTAX) guards
Modified: trunk/Source/WebKit2/DatabaseProcess/DatabaseProcess.cpp (199229 => 199230)
--- trunk/Source/WebKit2/DatabaseProcess/DatabaseProcess.cpp 2016-04-08 16:36:01 UTC (rev 199229)
+++ trunk/Source/WebKit2/DatabaseProcess/DatabaseProcess.cpp 2016-04-08 16:57:29 UTC (rev 199230)
@@ -98,7 +98,7 @@
IDBServer::IDBServer& DatabaseProcess::idbServer()
{
if (!m_idbServer)
- m_idbServer = IDBServer::IDBServer::create(indexedDatabaseDirectory());
+ m_idbServer = IDBServer::IDBServer::create(indexedDatabaseDirectory(), DatabaseProcess::singleton());
return *m_idbServer;
}
@@ -305,6 +305,33 @@
#endif
}
+void DatabaseProcess::grantSandboxExtensionsForBlobs(const Vector<String>& paths, const SandboxExtension::HandleArray& handles)
+{
+ ASSERT(paths.size() == handles.size());
+
+ for (size_t i = 0; i < paths.size(); ++i) {
+ auto result = m_blobTemporaryFileSandboxExtensions.add(paths[i], SandboxExtension::create(handles[i]));
+ ASSERT_UNUSED(result, result.isNewEntry);
+ }
+}
+
+void DatabaseProcess::prepareForAccessToTemporaryFile(const String& path)
+{
+ if (auto extension = m_blobTemporaryFileSandboxExtensions.get(path))
+ extension->consume();
+}
+
+void DatabaseProcess::accessToTemporaryFileComplete(const String& path)
+{
+ // We've either hard linked the temporary blob file to the database directory, copied it there,
+ // or the transaction is being aborted.
+ // In any of those cases, we can delete the temporary blob file now.
+ deleteFile(path);
+
+ if (auto extension = m_blobTemporaryFileSandboxExtensions.take(path))
+ extension->revoke();
+}
+
#if ENABLE(INDEXED_DATABASE)
Vector<RefPtr<WebCore::SecurityOrigin>> DatabaseProcess::indexedDatabaseOrigins()
{
Modified: trunk/Source/WebKit2/DatabaseProcess/DatabaseProcess.h (199229 => 199230)
--- trunk/Source/WebKit2/DatabaseProcess/DatabaseProcess.h 2016-04-08 16:36:01 UTC (rev 199229)
+++ trunk/Source/WebKit2/DatabaseProcess/DatabaseProcess.h 2016-04-08 16:57:29 UTC (rev 199230)
@@ -29,6 +29,8 @@
#if ENABLE(DATABASE_PROCESS)
#include "ChildProcess.h"
+#include "SandboxExtension.h"
+#include <WebCore/IDBBackingStore.h>
#include <WebCore/IDBServer.h>
#include <WebCore/UniqueIDBDatabase.h>
#include <wtf/NeverDestroyed.h>
@@ -45,7 +47,7 @@
enum class WebsiteDataType;
struct DatabaseProcessCreationParameters;
-class DatabaseProcess : public ChildProcess {
+class DatabaseProcess : public ChildProcess, public WebCore::IDBServer::IDBBackingStoreTemporaryFileHandler {
WTF_MAKE_NONCOPYABLE(DatabaseProcess);
friend class NeverDestroyed<DatabaseProcess>;
public:
@@ -65,6 +67,10 @@
void postDatabaseTask(std::unique_ptr<WebCore::CrossThreadTask>);
+ // WebCore::IDBServer::IDBBackingStoreFileHandler
+ void prepareForAccessToTemporaryFile(const String& path) final;
+ void accessToTemporaryFileComplete(const String& path) final;
+
private:
DatabaseProcess();
@@ -90,6 +96,7 @@
void fetchWebsiteData(WebCore::SessionID, OptionSet<WebsiteDataType> websiteDataTypes, uint64_t callbackID);
void deleteWebsiteData(WebCore::SessionID, OptionSet<WebsiteDataType> websiteDataTypes, std::chrono::system_clock::time_point modifiedSince, uint64_t callbackID);
void deleteWebsiteDataForOrigins(WebCore::SessionID, OptionSet<WebsiteDataType> websiteDataTypes, const Vector<WebCore::SecurityOriginData>& origins, uint64_t callbackID);
+ void grantSandboxExtensionsForBlobs(const Vector<String>& paths, const SandboxExtension::HandleArray&);
#if ENABLE(INDEXED_DATABASE)
Vector<RefPtr<WebCore::SecurityOrigin>> indexedDatabaseOrigins();
@@ -109,6 +116,8 @@
String m_indexedDatabaseDirectory;
RefPtr<WebCore::IDBServer::IDBServer> m_idbServer;
+
+ HashMap<String, RefPtr<SandboxExtension>> m_blobTemporaryFileSandboxExtensions;
#endif
Deque<std::unique_ptr<WebCore::CrossThreadTask>> m_databaseTasks;
Modified: trunk/Source/WebKit2/DatabaseProcess/DatabaseProcess.messages.in (199229 => 199230)
--- trunk/Source/WebKit2/DatabaseProcess/DatabaseProcess.messages.in 2016-04-08 16:36:01 UTC (rev 199229)
+++ trunk/Source/WebKit2/DatabaseProcess/DatabaseProcess.messages.in 2016-04-08 16:57:29 UTC (rev 199230)
@@ -32,6 +32,7 @@
FetchWebsiteData(WebCore::SessionID sessionID, OptionSet<WebKit::WebsiteDataType> websiteDataTypes, uint64_t callbackID)
DeleteWebsiteData(WebCore::SessionID sessionID, OptionSet<WebKit::WebsiteDataType> websiteDataTypes, std::chrono::system_clock::time_point modifiedSince, uint64_t callbackID)
DeleteWebsiteDataForOrigins(WebCore::SessionID sessionID, OptionSet<WebKit::WebsiteDataType> websiteDataTypes, Vector<WebCore::SecurityOriginData> origins, uint64_t callbackID)
+ GrantSandboxExtensionsForBlobs(Vector<String> paths, WebKit::SandboxExtension::HandleArray extensions)
}
#endif // ENABLE(DATABASE_PROCESS)
Modified: trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp (199229 => 199230)
--- trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp 2016-04-08 16:36:01 UTC (rev 199229)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp 2016-04-08 16:57:29 UTC (rev 199230)
@@ -301,10 +301,12 @@
for (auto& file : fileReferences)
file->revokeFileAccess();
- if (!m_connection || !m_connection->isValid())
- return;
+ NetworkProcess::singleton().grantSandboxExtensionsToDatabaseProcessForBlobs(fileNames, [this, protector, requestIdentifier, fileNames]() {
+ if (!m_connection || !m_connection->isValid())
+ return;
- m_connection->send(Messages::NetworkProcessConnection::DidWriteBlobsToTemporaryFiles(requestIdentifier, fileNames), 0);
+ m_connection->send(Messages::NetworkProcessConnection::DidWriteBlobsToTemporaryFiles(requestIdentifier, fileNames), 0);
+ });
});
}
Modified: trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp (199229 => 199230)
--- trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp 2016-04-08 16:36:01 UTC (rev 199229)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp 2016-04-08 16:57:29 UTC (rev 199230)
@@ -293,6 +293,21 @@
SessionTracker::destroySession(sessionID);
}
+void NetworkProcess::grantSandboxExtensionsToDatabaseProcessForBlobs(const Vector<String>& filenames, std::function<void ()> completionHandler)
+{
+ static uint64_t lastRequestID;
+
+ uint64_t requestID = ++lastRequestID;
+ m_sandboxExtensionForBlobsCompletionHandlers.set(requestID, completionHandler);
+ parentProcessConnection()->send(Messages::NetworkProcessProxy::GrantSandboxExtensionsToDatabaseProcessForBlobs(requestID, filenames), 0);
+}
+
+void NetworkProcess::didGrantSandboxExtensionsToDatabaseProcessForBlobs(uint64_t requestID)
+{
+ if (auto handler = m_sandboxExtensionForBlobsCompletionHandlers.take(requestID))
+ handler();
+}
+
static void fetchDiskCacheEntries(SessionID sessionID, OptionSet<WebsiteDataFetchOption> fetchOptions, std::function<void (Vector<WebsiteData::Entry>)> completionHandler)
{
#if ENABLE(NETWORK_CACHE)
Modified: trunk/Source/WebKit2/NetworkProcess/NetworkProcess.h (199229 => 199230)
--- trunk/Source/WebKit2/NetworkProcess/NetworkProcess.h 2016-04-08 16:36:01 UTC (rev 199229)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkProcess.h 2016-04-08 16:57:29 UTC (rev 199230)
@@ -112,6 +112,8 @@
void ensurePrivateBrowsingSession(WebCore::SessionID);
+ void grantSandboxExtensionsToDatabaseProcessForBlobs(const Vector<String>& filenames, std::function<void ()> completionHandler);
+
private:
NetworkProcess();
~NetworkProcess();
@@ -178,6 +180,8 @@
void getNetworkProcessStatistics(uint64_t callbackID);
void clearCacheForAllOrigins(uint32_t cachesToClear);
+ void didGrantSandboxExtensionsToDatabaseProcessForBlobs(uint64_t requestID);
+
#if USE(SOUP)
void setIgnoreTLSErrors(bool);
void userPreferredLanguagesChanged(const Vector<String>&);
@@ -200,6 +204,8 @@
typedef HashMap<const char*, std::unique_ptr<NetworkProcessSupplement>, PtrHash<const char*>> NetworkProcessSupplementMap;
NetworkProcessSupplementMap m_supplements;
+ HashMap<uint64_t, std::function<void ()>> m_sandboxExtensionForBlobsCompletionHandlers;
+
#if PLATFORM(COCOA)
void platformInitializeNetworkProcessCocoa(const NetworkProcessCreationParameters&);
Modified: trunk/Source/WebKit2/NetworkProcess/NetworkProcess.messages.in (199229 => 199230)
--- trunk/Source/WebKit2/NetworkProcess/NetworkProcess.messages.in 2016-04-08 16:36:01 UTC (rev 199229)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkProcess.messages.in 2016-04-08 16:57:29 UTC (rev 199230)
@@ -67,4 +67,6 @@
PrepareToSuspend()
CancelPrepareToSuspend()
ProcessDidResume()
+
+ DidGrantSandboxExtensionsToDatabaseProcessForBlobs(uint64_t requestID)
}
Modified: trunk/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.cpp (199229 => 199230)
--- trunk/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.cpp 2016-04-08 16:36:01 UTC (rev 199229)
+++ trunk/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.cpp 2016-04-08 16:57:29 UTC (rev 199230)
@@ -28,9 +28,11 @@
#include "AuthenticationChallengeProxy.h"
#include "CustomProtocolManagerProxyMessages.h"
+#include "DatabaseProcessMessages.h"
#include "DownloadProxyMessages.h"
#include "NetworkProcessCreationParameters.h"
#include "NetworkProcessMessages.h"
+#include "SandboxExtension.h"
#include "WebProcessMessages.h"
#include "WebProcessPool.h"
#include "WebsiteData.h"
@@ -269,6 +271,19 @@
callback();
}
+void NetworkProcessProxy::grantSandboxExtensionsToDatabaseProcessForBlobs(uint64_t requestID, const Vector<String>& paths)
+{
+ SandboxExtension::HandleArray extensions;
+ extensions.allocate(paths.size());
+ for (size_t i = 0; i < paths.size(); ++i) {
+ // ReadWrite is required for creating hard links as well as deleting the temporary file, which the DatabaseProcess will do.
+ SandboxExtension::createHandle(paths[i], SandboxExtension::ReadWrite, extensions[i]);
+ }
+
+ m_processPool.sendToDatabaseProcessRelaunchingIfNecessary(Messages::DatabaseProcess::GrantSandboxExtensionsForBlobs(paths, extensions));
+ connection()->send(Messages::NetworkProcess::DidGrantSandboxExtensionsToDatabaseProcessForBlobs(requestID), 0);
+}
+
void NetworkProcessProxy::didFinishLaunching(ProcessLauncher* launcher, IPC::Connection::Identifier connectionIdentifier)
{
ChildProcessProxy::didFinishLaunching(launcher, connectionIdentifier);
Modified: trunk/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.h (199229 => 199230)
--- trunk/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.h 2016-04-08 16:36:01 UTC (rev 199229)
+++ trunk/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.h 2016-04-08 16:57:29 UTC (rev 199230)
@@ -106,6 +106,7 @@
void didFetchWebsiteData(uint64_t callbackID, const WebsiteData&);
void didDeleteWebsiteData(uint64_t callbackID);
void didDeleteWebsiteDataForOrigins(uint64_t callbackID);
+ void grantSandboxExtensionsToDatabaseProcessForBlobs(uint64_t requestID, const Vector<String>& paths);
void logSampledDiagnosticMessage(uint64_t pageID, const String& message, const String& description);
void logSampledDiagnosticMessageWithResult(uint64_t pageID, const String& message, const String& description, uint32_t result);
void logSampledDiagnosticMessageWithValue(uint64_t pageID, const String& message, const String& description, const String& value);
Modified: trunk/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.messages.in (199229 => 199230)
--- trunk/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.messages.in 2016-04-08 16:36:01 UTC (rev 199229)
+++ trunk/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.messages.in 2016-04-08 16:57:29 UTC (rev 199230)
@@ -29,6 +29,8 @@
DidDeleteWebsiteData(uint64_t callbackID)
DidDeleteWebsiteDataForOrigins(uint64_t callbackID)
+ GrantSandboxExtensionsToDatabaseProcessForBlobs(uint64_t requestID, Vector<String> paths)
+
ProcessReadyToSuspend()
SetIsHoldingLockedFiles(bool isHoldingLockedFiles)