Skip to content

Commit

Permalink
Cherry-pick 8e9f2eb. rdar://problem/113878001
Browse files Browse the repository at this point in the history
    ServiceWorkerRegistration data is not deleted correctly
    https://bugs.webkit.org/show_bug.cgi?id=260163
    rdar://112092827

    Reviewed by Brent Fulgham.

    bindText() returns error code and 0 (SQLITE_OK) means the operation succeeds, so updateRegistrations should not return
    early.

    API Test: WKWebsiteDataStore.RemoveServiceWorkerDataByOrigin

    * Source/WebCore/workers/service/server/SWRegistrationDatabase.cpp:
    (WebCore::SWRegistrationDatabase::updateRegistrations):
    * Tools/TestWebKitAPI/Tests/WebKitCocoa/WebsiteDataStoreCustomPaths.mm:

    Canonical link: https://commits.webkit.org/266882@main

Identifier: 265870.379@safari-7616-branch
  • Loading branch information
szewai authored and Dan Robson committed Aug 15, 2023
1 parent 80f77ba commit f9c8783
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ std::optional<Vector<ServiceWorkerScripts>> SWRegistrationDatabase::updateRegist

for (auto& registration : registrationsToDelete) {
auto statement = cachedStatement(StatementType::DeleteRecord);
if (!statement || !statement->bindText(1, registration.toDatabaseKey()) || statement->step() != SQLITE_DONE) {
if (!statement || statement->bindText(1, registration.toDatabaseKey()) != SQLITE_OK || statement->step() != SQLITE_DONE) {
RELEASE_LOG_ERROR(Storage, "SWRegistrationDatabase::updateRegistrations failed to delete record (%d) - %s", m_database->lastError(), m_database->lastErrorMsg());
return std::nullopt;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1700,7 +1700,7 @@ function install()
EXPECT_FALSE([fileManager fileExistsAtPath:serviceWorkerDatabaseFile.path]);
}

TEST(WKWebsiteDataStore, RemoveServiceWorkerData)
static RetainPtr<WKWebsiteDataStore> createCustomWebsiteDataStoreForServiceWorker(TestWebKitAPI::HTTPServer* server)
{
[WKWebsiteDataStore _allowWebsiteDataRecordsForAllOrigins];
auto websiteDataStoreConfiguration = adoptNS([[_WKWebsiteDataStoreConfiguration alloc] init]);
Expand All @@ -1714,19 +1714,14 @@ function install()
}];
TestWebKitAPI::Util::run(&done);

TestWebKitAPI::HTTPServer server({
{ "/"_s, { mainBytes } },
{ "/migratetest/sw.js"_s, { { { "Content-Type"_s, "application/javascript"_s } }, scriptBytes } },
});

// Ensure web view is closed, so ServiceWorker directory is not in use and can be removed.
@autoreleasepool {
auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
[configuration setWebsiteDataStore:websiteDataStore.get()];
auto messageHandler = adoptNS([[WebsiteDataStoreCustomPathsMessageHandler alloc] init]);
[[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"testHandler"];
auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
[webView loadRequest:server.request()];
[webView loadRequest:server->request()];
EXPECT_WK_STREQ("Message from ServiceWorker: Hello", getNextMessage().body);

// Ensure data is stored to disk.
Expand All @@ -1737,20 +1732,83 @@ function install()
TestWebKitAPI::Util::run(&done);
}

return websiteDataStore;
}

TEST(WKWebsiteDataStore, RemoveServiceWorkerData)
{
TestWebKitAPI::HTTPServer server({
{ "/"_s, { mainBytes } },
{ "/migratetest/sw.js"_s, { { { "Content-Type"_s, "application/javascript"_s } }, scriptBytes } },
});

auto websiteDataStore = createCustomWebsiteDataStoreForServiceWorker(&server);
__block NSString *serviceWorkerDirectoryString = nil;
auto url = [server.request() URL];
done = false;
[websiteDataStore _originDirectoryForTesting:url topOrigin:url type:WKWebsiteDataTypeServiceWorkerRegistrations completionHandler:^(NSString *result) {
[websiteDataStore.get() _originDirectoryForTesting:url topOrigin:url type:WKWebsiteDataTypeServiceWorkerRegistrations completionHandler:^(NSString *result) {
serviceWorkerDirectoryString = result;
done = true;
}];
TestWebKitAPI::Util::run(&done);
EXPECT_TRUE([[NSFileManager defaultManager] fileExistsAtPath:serviceWorkerDirectoryString]);

auto dataTypes = [NSSet setWithObjects:WKWebsiteDataTypeServiceWorkerRegistrations, nil];
done = false;
[websiteDataStore removeDataOfTypes:[NSSet setWithObjects:WKWebsiteDataTypeServiceWorkerRegistrations, nil] modifiedSince:[NSDate distantPast] completionHandler:^() {
[websiteDataStore removeDataOfTypes:dataTypes modifiedSince:[NSDate distantPast] completionHandler:^() {
done = true;
}];
TestWebKitAPI::Util::run(&done);
EXPECT_FALSE([[NSFileManager defaultManager] fileExistsAtPath:serviceWorkerDirectoryString]);

done = false;
[websiteDataStore fetchDataRecordsOfTypes:dataTypes completionHandler:^(NSArray<WKWebsiteDataRecord *> * records) {
EXPECT_EQ([records count], 0u);
done = true;
}];
TestWebKitAPI::Util::run(&done);
}

TEST(WKWebsiteDataStore, RemoveServiceWorkerDataByOrigin)
{
TestWebKitAPI::HTTPServer server({
{ "/"_s, { mainBytes } },
{ "/migratetest/sw.js"_s, { { { "Content-Type"_s, "application/javascript"_s } }, scriptBytes } },
});
auto websiteDataStore = createCustomWebsiteDataStoreForServiceWorker(&server);

// Fetch origin record.
auto dataTypes = [NSSet setWithObjects:WKWebsiteDataTypeServiceWorkerRegistrations, nil];
__block RetainPtr<NSArray<WKWebsiteDataRecord *>> records;
done = false;
[websiteDataStore fetchDataRecordsOfTypes:dataTypes completionHandler:^(NSArray<WKWebsiteDataRecord *> * dataRecords) {
records = dataRecords;
done = true;
}];
TestWebKitAPI::Util::run(&done);
EXPECT_EQ([records count], 1u);
EXPECT_WK_STREQ([[records firstObject] displayName], @"127.0.0.1");

// Delete data by origin.
done = false;
[websiteDataStore removeDataOfTypes:dataTypes forDataRecords:records.get() completionHandler:^() {
done = true;
}];
TestWebKitAPI::Util::run(&done);

// Kill network process to ensure data is read from disk.
pid_t networkProcessIdentifier = [websiteDataStore _networkProcessIdentifier];
EXPECT_NE(networkProcessIdentifier, 0);
kill(networkProcessIdentifier, SIGKILL);
while (!kill(networkProcessIdentifier, 0))
TestWebKitAPI::Util::spinRunLoop();

// Verify record is deleted.
done = false;
[websiteDataStore fetchDataRecordsOfTypes:dataTypes completionHandler:^(NSArray<WKWebsiteDataRecord *> * dataRecords) {
records = dataRecords;
done = true;
}];
TestWebKitAPI::Util::run(&done);
EXPECT_EQ([records count], 0u);
}

0 comments on commit f9c8783

Please sign in to comment.