⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 294726 in webkit


Ignore:
Timestamp:
May 23, 2022, 9:00:18 PM (4 years ago)
Author:
Ben Nham
Message:

Fix webpushd crash when removing notification permissions
https://bugs.webkit.org/show_bug.cgi?id=240737

Reviewed by Chris Dumez and Geoffrey Garen.

When removing notification permissions for an origin, webpushd crashes because of a RELEASE_ASSERT
that fires in AppBundleRequest::start when INSTALL_COORDINATION_BUNDLES isn't enabled and mock
bundles aren't enabled.

Fix this by removing the calls into AppBundleRequest when INSTALL_COORDINATION_BUNDLES isn't enabled.
Those requests are only meant to run when that feature is enabled.

  • Tools/TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm: Only run the permission management test when INSTALL_COORDINATION_BUNDLES is enabled (e.g. on iOS); that is the only time it makes sense to test that codepath.
  • Source/WebKit/webpushd/WebPushDaemon.h:
  • Source/WebKit/webpushd/WebPushDaemon.mm:

(WebPushD::Daemon::deletePushRegistration):
(WebPushD::Daemon::deletePushAndNotificationRegistration):

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

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/webpushd/WebPushDaemon.h

    r293060 r294726  
    7575    void requestSystemNotificationPermission(ClientConnection*, const String&, CompletionHandler<void(bool)>&& replySender);
    7676    void getOriginsWithPushAndNotificationPermissions(ClientConnection*, CompletionHandler<void(const Vector<String>&)>&& replySender);
     77    void deletePushRegistration(const String&, const String&, CompletionHandler<void()>&&);
    7778    void deletePushAndNotificationRegistration(ClientConnection*, const String& originString, CompletionHandler<void(const String&)>&& replySender);
    7879    void setDebugModeIsEnabled(ClientConnection*, bool);
  • trunk/Source/WebKit/webpushd/WebPushDaemon.mm

    r293060 r294726  
    506506}
    507507
     508void Daemon::deletePushRegistration(const String& bundleIdentifier, const String& originString, CompletionHandler<void()>&& callback)
     509{
     510    runAfterStartingPushService([this, bundleIdentifier, originString, callback = WTFMove(callback)]() mutable {
     511        if (!m_pushService) {
     512            callback();
     513            return;
     514        }
     515
     516        m_pushService->removeRecordsForBundleIdentifierAndOrigin(bundleIdentifier, originString, [callback = WTFMove(callback)](auto&&) mutable {
     517            callback();
     518        });
     519    });
     520}
     521
    508522void Daemon::deletePushAndNotificationRegistration(ClientConnection* connection, const String& originString, CompletionHandler<void(const String&)>&& replySender)
    509523{
     
    513527    }
    514528
     529#if ENABLE(INSTALL_COORDINATION_BUNDLES)
    515530    connection->enqueueAppBundleRequest(makeUnique<AppBundleDeletionRequest>(*connection, originString, [this, originString = String { originString }, replySender = WTFMove(replySender), bundleIdentifier = connection->hostAppCodeSigningIdentifier()](auto result) mutable {
    516         runAfterStartingPushService([this, bundleIdentifier = WTFMove(bundleIdentifier), originString = WTFMove(originString), replySender = WTFMove(replySender), result]() mutable {
    517             if (!m_pushService) {
    518                 replySender(result);
    519                 return;
    520             }
    521 
    522             m_pushService->removeRecordsForBundleIdentifierAndOrigin(bundleIdentifier, originString, [replySender = WTFMove(replySender), result](auto&&) mutable {
    523                 replySender(result);
    524             });
     531        deletePushRegistration(bundleIdentifier, originString, [replySender = WTFMove(replySender), result]() mutable {
     532            replySender(result);
    525533        });
    526534    }));
     535#else
     536    deletePushRegistration(connection->hostAppCodeSigningIdentifier(), originString, [replySender = WTFMove(replySender)]() mutable {
     537        replySender(emptyString());
     538    });
     539#endif
    527540}
    528541
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm

    r294425 r294726  
    323323}
    324324
    325 TEST(WebPushD, PermissionManagement)
    326 {
    327     NSURL *tempDirectory = setUpTestWebPushD();
    328 
    329     auto dataStoreConfiguration = adoptNS([_WKWebsiteDataStoreConfiguration new]);
    330     dataStoreConfiguration.get().webPushMachServiceName = @"org.webkit.webpushtestdaemon.service";
    331     dataStoreConfiguration.get().webPushDaemonUsesMockBundlesForTesting = YES;
    332     auto dataStore = adoptNS([[WKWebsiteDataStore alloc] _initWithConfiguration:dataStoreConfiguration.get()]);
    333 
    334     auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    335     configuration.get().websiteDataStore = dataStore.get();
    336     [configuration.get().preferences _setNotificationsEnabled:YES];
    337     for (_WKExperimentalFeature *feature in [WKPreferences _experimentalFeatures]) {
    338         if ([feature.key isEqualToString:@"BuiltInNotificationsEnabled"])
    339             [[configuration preferences] _setEnabled:YES forFeature:feature];
    340     }
    341 
    342     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
    343     auto uiDelegate = adoptNS([[NotificationPermissionDelegate alloc] init]);
    344     [webView setUIDelegate:uiDelegate.get()];
    345     [webView synchronouslyLoadHTMLString:@"" baseURL:[NSURL URLWithString:@"https://example.org"]];
    346     [webView evaluateJavaScript:@"Notification.requestPermission().then(() => { alert('done') })" completionHandler:nil];
    347     TestWebKitAPI::Util::run(&alertReceived);
    348 
    349     static bool originOperationDone = false;
    350     static RetainPtr<WKSecurityOrigin> origin;
    351     [dataStore _getOriginsWithPushAndNotificationPermissions:^(NSSet<WKSecurityOrigin *> *origins) {
    352         EXPECT_EQ([origins count], 1u);
    353         origin = [origins anyObject];
    354         originOperationDone = true;
    355     }];
    356 
    357     TestWebKitAPI::Util::run(&originOperationDone);
    358 
    359     EXPECT_WK_STREQ(origin.get().protocol, "https");
    360     EXPECT_WK_STREQ(origin.get().host, "example.org");
    361 
    362     // If we failed to retrieve an expected origin, we will have failed the above checks
    363     if (!origin) {
    364         cleanUpTestWebPushD(tempDirectory);
    365         return;
    366     }
    367 
    368     originOperationDone = false;
    369     [dataStore _deletePushAndNotificationRegistration:origin.get() completionHandler:^(NSError *error) {
    370         EXPECT_FALSE(!!error);
    371         originOperationDone = true;
    372     }];
    373 
    374     TestWebKitAPI::Util::run(&originOperationDone);
    375 
    376     originOperationDone = false;
    377     [dataStore _getOriginsWithPushAndNotificationPermissions:^(NSSet<WKSecurityOrigin *> *origins) {
    378         EXPECT_EQ([origins count], 0u);
    379         originOperationDone = true;
    380     }];
    381     TestWebKitAPI::Util::run(&originOperationDone);
    382 
    383     cleanUpTestWebPushD(tempDirectory);
    384 }
    385 
    386325static void clearWebsiteDataStore(WKWebsiteDataStore *store)
    387326{
     
    939878#if ENABLE(INSTALL_COORDINATION_BUNDLES)
    940879#if USE(APPLE_INTERNAL_SDK)
     880TEST(WebPushD, PermissionManagement)
     881{
     882    NSURL *tempDirectory = setUpTestWebPushD();
     883
     884    auto dataStoreConfiguration = adoptNS([_WKWebsiteDataStoreConfiguration new]);
     885    dataStoreConfiguration.get().webPushMachServiceName = @"org.webkit.webpushtestdaemon.service";
     886    dataStoreConfiguration.get().webPushDaemonUsesMockBundlesForTesting = YES;
     887    auto dataStore = adoptNS([[WKWebsiteDataStore alloc] _initWithConfiguration:dataStoreConfiguration.get()]);
     888
     889    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     890    configuration.get().websiteDataStore = dataStore.get();
     891    [configuration.get().preferences _setNotificationsEnabled:YES];
     892    for (_WKExperimentalFeature *feature in [WKPreferences _experimentalFeatures]) {
     893        if ([feature.key isEqualToString:@"BuiltInNotificationsEnabled"])
     894            [[configuration preferences] _setEnabled:YES forFeature:feature];
     895    }
     896
     897    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
     898    auto uiDelegate = adoptNS([[NotificationPermissionDelegate alloc] init]);
     899    [webView setUIDelegate:uiDelegate.get()];
     900    [webView synchronouslyLoadHTMLString:@"" baseURL:[NSURL URLWithString:@"https://example.org"]];
     901    [webView evaluateJavaScript:@"Notification.requestPermission().then(() => { alert('done') })" completionHandler:nil];
     902    TestWebKitAPI::Util::run(&alertReceived);
     903
     904    static bool originOperationDone = false;
     905    static RetainPtr<WKSecurityOrigin> origin;
     906    [dataStore _getOriginsWithPushAndNotificationPermissions:^(NSSet<WKSecurityOrigin *> *origins) {
     907        EXPECT_EQ([origins count], 1u);
     908        origin = [origins anyObject];
     909        originOperationDone = true;
     910    }];
     911
     912    TestWebKitAPI::Util::run(&originOperationDone);
     913
     914    EXPECT_WK_STREQ(origin.get().protocol, "https");
     915    EXPECT_WK_STREQ(origin.get().host, "example.org");
     916
     917    // If we failed to retrieve an expected origin, we will have failed the above checks
     918    if (!origin) {
     919        cleanUpTestWebPushD(tempDirectory);
     920        return;
     921    }
     922
     923    originOperationDone = false;
     924    [dataStore _deletePushAndNotificationRegistration:origin.get() completionHandler:^(NSError *error) {
     925        EXPECT_FALSE(!!error);
     926        originOperationDone = true;
     927    }];
     928
     929    TestWebKitAPI::Util::run(&originOperationDone);
     930
     931    originOperationDone = false;
     932    [dataStore _getOriginsWithPushAndNotificationPermissions:^(NSSet<WKSecurityOrigin *> *origins) {
     933        EXPECT_EQ([origins count], 0u);
     934        originOperationDone = true;
     935    }];
     936    TestWebKitAPI::Util::run(&originOperationDone);
     937
     938    cleanUpTestWebPushD(tempDirectory);
     939}
     940
    941941static void deleteAllRegistrationsForDataStore(WKWebsiteDataStore *dataStore)
    942942{
Note: See TracChangeset for help on using the changeset viewer.