Skip to content

Commit

Permalink
Invalidate extension's reference to database after it's been deleted.
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=271020
rdar://124037961

Reviewed by Sihui Liu and Timothy Hatcher.

When an extension's SQL database is deleted, send a notification to the WebExtensionController to
invalidate the extension context's reference to the database. A distrubuted notification here
is important since this deletion may happen from a process where the WebExtensionContext isn't
loaded.

* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionControllerCocoa.mm:
(-[_WKWebExtensionControllerHelper initWithWebExtensionController:]):
(-[_WKWebExtensionControllerHelper _didDeleteLocalStorage:]):
(WebKit::WebExtensionController::createWebExtensionControllerHelper):
(WebKit::WebExtensionController::removeData):
* Source/WebKit/UIProcess/Extensions/WebExtensionController.cpp:
(WebKit::WebExtensionController::WebExtensionController):
* Source/WebKit/UIProcess/Extensions/WebExtensionController.h:

Canonical link: https://commits.webkit.org/276202@main
  • Loading branch information
kiaraarose committed Mar 15, 2024
1 parent e6d4d4d commit 5ac28a0
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 4 deletions.
18 changes: 17 additions & 1 deletion Source/WebKit/Platform/spi/Cocoa/FoundationSPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,26 @@

#include <Foundation/NSPrivateDecls.h>

#if PLATFORM(IOS_FAMILY)
#include <Foundation/NSDistributedNotificationCenter.h>
#endif

#else

NS_ASSUME_NONNULL_BEGIN

@interface NSBundle ()
- (CFBundleRef)_cfBundle;
- (null_unspecified CFBundleRef)_cfBundle;
@end

#if PLATFORM(IOS_FAMILY)
@interface NSDistributedNotificationCenter : NSNotificationCenter
+ (NSDistributedNotificationCenter *)defaultCenter;
- (void)addObserver:(id)observer selector:(SEL)aSelector name:(nullable NSNotificationName)aName object:(nullable NSString *)anObject;
- (void)postNotificationName:(NSNotificationName)aName object:(nullable NSString *)anObject userInfo:(nullable NSDictionary *)aUserInfo;
@end
#endif

NS_ASSUME_NONNULL_END

#endif // USE(APPLE_INTERNAL_SDK)
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@

#import <WebKit/_WKWebExtensionControllerConfiguration.h>

// FIXME: Remove once https://commits.webkit.org/275999@main is in the SDK.
#define HAVE_UPDATED_WEB_EXTENSION_CONTROLLER_STORAGE_DIRECTORY_PATH 1

NS_ASSUME_NONNULL_BEGIN

@interface _WKWebExtensionControllerConfiguration ()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,62 @@
#import <wtf/NeverDestroyed.h>
#import <wtf/text/WTFString.h>

#if PLATFORM(IOS_FAMILY)
#import "FoundationSPI.h"
#endif

static constexpr Seconds purgeMatchedRulesInterval = 5_min;

static NSString * const WebExtensionUniqueIdentifierKey = @"uniqueIdentifier";
static NSString * const WebExtensionLocalStorageWasDeletedNotification = @"WebExtensionLocalStorageWasDeleted";

using namespace WebKit;

@interface _WKWebExtensionControllerHelper : NSObject {
WeakPtr<WebKit::WebExtensionController> _webExtensionController;
}

- (instancetype)initWithWebExtensionController:(WebKit::WebExtensionController&)controller;

@end

@implementation _WKWebExtensionControllerHelper

- (instancetype)initWithWebExtensionController:(WebKit::WebExtensionController&)controller
{
if (!(self = [super init]))
return nil;

_webExtensionController = controller;

[NSDistributedNotificationCenter.defaultCenter addObserver:self selector:@selector(_didDeleteLocalStorage:) name:WebExtensionLocalStorageWasDeletedNotification object:nil];

return self;
}

- (void)_didDeleteLocalStorage:(NSNotification *)notification
{
NSString *uniqueIdentifier = objectForKey<NSString>(notification.userInfo, WebExtensionUniqueIdentifierKey);
if (!uniqueIdentifier)
return;

if (!_webExtensionController)
return;

if (RefPtr context = _webExtensionController->extensionContext(uniqueIdentifier))
context->invalidateStorage();
}

@end

namespace WebKit {

void WebExtensionController::initializePlatform()
{
ASSERT(!m_webExtensionControllerHelper);
m_webExtensionControllerHelper = [[_WKWebExtensionControllerHelper alloc] initWithWebExtensionController:*this];
}

String WebExtensionController::storageDirectory(WebExtensionContext& extensionContext) const
{
if (m_configuration->storageIsPersistent() && extensionContext.hasCustomUniqueIdentifier())
Expand Down Expand Up @@ -167,9 +219,8 @@
if (!storage)
continue;

removeStorage(storage, type, makeBlockPtr([aggregator, extensionContext = RefPtr { extensionContext }]() mutable {
if (extensionContext)
extensionContext->invalidateStorage();
removeStorage(storage, type, makeBlockPtr([aggregator, uniqueIdentifier, extensionContext = RefPtr { extensionContext }]() mutable {
[NSDistributedNotificationCenter.defaultCenter postNotificationName:WebExtensionLocalStorageWasDeletedNotification object:nil userInfo:@{ WebExtensionUniqueIdentifierKey: uniqueIdentifier }];
}));
}
}
Expand Down
2 changes: 2 additions & 0 deletions Source/WebKit/UIProcess/Extensions/WebExtensionController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ WebExtensionController::WebExtensionController(Ref<WebExtensionControllerConfigu
ASSERT(!get(identifier()));
webExtensionControllers().add(identifier(), *this);

initializePlatform();

// A freshly created extension controller will be used to determine if the startup event
// should be fired for any loaded extensions during a brief time window. Start a timer
// when the first extension is about to be loaded.
Expand Down
4 changes: 4 additions & 0 deletions Source/WebKit/UIProcess/Extensions/WebExtensionController.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
OBJC_CLASS NSError;
OBJC_CLASS NSMenu;
OBJC_CLASS _WKWebExtensionStorageSQLiteStore;
OBJC_CLASS _WKWebExtensionControllerHelper;
OBJC_PROTOCOL(_WKWebExtensionControllerDelegatePrivate);

#ifdef __OBJC__
Expand Down Expand Up @@ -174,6 +175,8 @@ class WebExtensionController : public API::ObjectImpl<API::Object::Type::WebExte
// IPC::MessageReceiver
void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;

void initializePlatform();

void addProcessPool(WebProcessPool&);
void removeProcessPool(WebProcessPool&);

Expand Down Expand Up @@ -226,6 +229,7 @@ class WebExtensionController : public API::ObjectImpl<API::Object::Type::WebExte

Ref<WebExtensionControllerConfiguration> m_configuration;

RetainPtr<_WKWebExtensionControllerHelper> m_webExtensionControllerHelper;
WebExtensionContextSet m_extensionContexts;
WebExtensionContextBaseURLMap m_extensionContextBaseURLMap;
WebPageProxySet m_pages;
Expand Down

0 comments on commit 5ac28a0

Please sign in to comment.