Title: [226705] trunk/Source/WebCore
Revision
226705
Author
[email protected]
Date
2018-01-10 02:16:40 -0800 (Wed, 10 Jan 2018)

Log Message

Add Service Worker CSP persistency
https://bugs.webkit.org/show_bug.cgi?id=181434

Patch by Youenn Fablet <[email protected]> on 2018-01-10
Reviewed by Alex Christensen.

Covered by manual testing.
Future work on service worker test infrastructure should allow automating such tests.

Add support for service worker CSP data persistency.
Add a version parameter to increment each time the schema is changing.
This allows the same store to be used by multiple WebKits.

* workers/service/server/RegistrationDatabase.cpp:
(WebCore::v1RecordsTableSchema):
(WebCore::RegistrationDatabase::openSQLiteDatabase):
(WebCore::RegistrationDatabase::doPushChanges):
(WebCore::RegistrationDatabase::importRecords):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (226704 => 226705)


--- trunk/Source/WebCore/ChangeLog	2018-01-10 10:15:42 UTC (rev 226704)
+++ trunk/Source/WebCore/ChangeLog	2018-01-10 10:16:40 UTC (rev 226705)
@@ -1,3 +1,23 @@
+2018-01-10  Youenn Fablet  <[email protected]>
+
+        Add Service Worker CSP persistency
+        https://bugs.webkit.org/show_bug.cgi?id=181434
+
+        Reviewed by Alex Christensen.
+
+        Covered by manual testing.
+        Future work on service worker test infrastructure should allow automating such tests.
+
+        Add support for service worker CSP data persistency.
+        Add a version parameter to increment each time the schema is changing.
+        This allows the same store to be used by multiple WebKits.
+
+        * workers/service/server/RegistrationDatabase.cpp:
+        (WebCore::v1RecordsTableSchema):
+        (WebCore::RegistrationDatabase::openSQLiteDatabase):
+        (WebCore::RegistrationDatabase::doPushChanges):
+        (WebCore::RegistrationDatabase::importRecords):
+
 2018-01-10  Antti Koivisto  <[email protected]>
 
         Invalidate current element style on class change accurately

Modified: trunk/Source/WebCore/workers/service/server/RegistrationDatabase.cpp (226704 => 226705)


--- trunk/Source/WebCore/workers/service/server/RegistrationDatabase.cpp	2018-01-10 10:15:42 UTC (rev 226704)
+++ trunk/Source/WebCore/workers/service/server/RegistrationDatabase.cpp	2018-01-10 10:16:40 UTC (rev 226705)
@@ -40,12 +40,17 @@
 #include <wtf/MainThread.h>
 #include <wtf/NeverDestroyed.h>
 #include <wtf/Scope.h>
+#include <wtf/persistence/PersistentCoders.h>
+#include <wtf/persistence/PersistentDecoder.h>
+#include <wtf/persistence/PersistentEncoder.h>
 
 namespace WebCore {
 
+static const int schemaVersion = 1;
+
 static const String v1RecordsTableSchema(const String& tableName)
 {
-    return makeString("CREATE TABLE ", tableName, " (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE, origin TEXT NOT NULL ON CONFLICT FAIL, scopeURL TEXT NOT NULL ON CONFLICT FAIL, topOrigin TEXT NOT NULL ON CONFLICT FAIL, lastUpdateCheckTime DOUBLE NOT NULL ON CONFLICT FAIL, updateViaCache TEXT NOT NULL ON CONFLICT FAIL, scriptURL TEXT NOT NULL ON CONFLICT FAIL, script TEXT NOT NULL ON CONFLICT FAIL, workerType TEXT NOT NULL ON CONFLICT FAIL)");
+    return makeString("CREATE TABLE ", tableName, " (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE, origin TEXT NOT NULL ON CONFLICT FAIL, scopeURL TEXT NOT NULL ON CONFLICT FAIL, topOrigin TEXT NOT NULL ON CONFLICT FAIL, lastUpdateCheckTime DOUBLE NOT NULL ON CONFLICT FAIL, updateViaCache TEXT NOT NULL ON CONFLICT FAIL, scriptURL TEXT NOT NULL ON CONFLICT FAIL, script TEXT NOT NULL ON CONFLICT FAIL, workerType TEXT NOT NULL ON CONFLICT FAIL, contentSecurityPolicy BLOB NOT NULL ON CONFLICT FAIL)");
 }
 
 static const String v1RecordsTableSchema()
@@ -65,7 +70,7 @@
 static const String& databaseFilename()
 {
     ASSERT(isMainThread());
-    static NeverDestroyed<String> filename = "ServiceWorkerRegistrations.sqlite3";
+    static NeverDestroyed<String> filename = makeString("ServiceWorkerRegistrations-", String::number(schemaVersion), ".sqlite3");
     return filename;
 }
 
@@ -118,7 +123,7 @@
     errorMessage = importRecords();
     if (!errorMessage.isNull())
         return;
-    
+
     scopeExit.release();
 }
 
@@ -258,7 +263,7 @@
     SQLiteTransaction transaction(*m_database);
     transaction.begin();
 
-    SQLiteStatement sql(*m_database, ASCIILiteral("INSERT INTO Records VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"));
+    SQLiteStatement sql(*m_database, ASCIILiteral("INSERT INTO Records VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"));
     if (sql.prepare() != SQLITE_OK) {
         RELEASE_LOG_ERROR(ServiceWorker, "Failed to prepare statement to store registration data into records table (%i) - %s", m_database->lastError(), m_database->lastErrorMsg());
         return;
@@ -277,6 +282,9 @@
             continue;
         }
 
+        WTF::Persistence::Encoder encoder;
+        data.contentSecurityPolicy.encode(encoder);
+
         if (sql.bindText(1, data.registration.key.toDatabaseKey()) != SQLITE_OK
             || sql.bindText(2, data.registration.scopeURL.protocolHostAndPort()) != SQLITE_OK
             || sql.bindText(3, data.registration.scopeURL.path()) != SQLITE_OK
@@ -286,6 +294,7 @@
             || sql.bindText(7, data.scriptURL.string()) != SQLITE_OK
             || sql.bindText(8, data.script) != SQLITE_OK
             || sql.bindText(9, workerTypeToString(data.workerType)) != SQLITE_OK
+            || sql.bindBlob(10, encoder.buffer(), encoder.bufferSize()) != SQLITE_OK
             || sql.step() != SQLITE_DONE) {
             RELEASE_LOG_ERROR(ServiceWorker, "Failed to store registration data into records table (%i) - %s", m_database->lastError(), m_database->lastErrorMsg());
             return;
@@ -318,6 +327,13 @@
         auto script = sql.getColumnText(7);
         auto workerType = stringToWorkerType(sql.getColumnText(8));
 
+        Vector<uint8_t> contentSecurityPolicyData;
+        sql.getColumnBlobAsVector(9, contentSecurityPolicyData);
+        WTF::Persistence::Decoder decoder(contentSecurityPolicyData.data(), contentSecurityPolicyData.size());
+        ContentSecurityPolicyResponseHeaders contentSecurityPolicy;
+        if (contentSecurityPolicyData.size() && !ContentSecurityPolicyResponseHeaders::decode(decoder, contentSecurityPolicy))
+            continue;
+
         // Validate the input for this registration.
         // If any part of this input is invalid, let's skip this registration.
         // FIXME: Should we return an error skipping *all* registrations?
@@ -328,7 +344,7 @@
         auto registrationIdentifier = generateObjectIdentifier<ServiceWorkerRegistrationIdentifierType>();
         auto serviceWorkerData = ServiceWorkerData { workerIdentifier, scriptURL, ServiceWorkerState::Activated, *workerType, registrationIdentifier };
         auto registration = ServiceWorkerRegistrationData { WTFMove(*key), registrationIdentifier, URL(originURL, scopePath), *updateViaCache, lastUpdateCheckTime, std::nullopt, std::nullopt, WTFMove(serviceWorkerData) };
-        auto contextData = ServiceWorkerContextData { std::nullopt, WTFMove(registration), workerIdentifier, WTFMove(script), { }, WTFMove(scriptURL), *workerType, true };
+        auto contextData = ServiceWorkerContextData { std::nullopt, WTFMove(registration), workerIdentifier, WTFMove(script), WTFMove(contentSecurityPolicy), WTFMove(scriptURL), *workerType, true };
 
         postTaskReply(createCrossThreadTask(*this, &RegistrationDatabase::addRegistrationToStore, WTFMove(contextData)));
     }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to