Skip to content

Commit

Permalink
Add a subclass of _WKWebExtensionSQLiteStore responsible for managing…
Browse files Browse the repository at this point in the history
… dynamic and session DNR rules

https://bugs.webkit.org/show_bug.cgi?id=265965
<rdar://problem/119274953>

Reviewed by Timothy Hatcher.

This will be used for dynamic and session rules in the WebKit Web Extensions implementation. It was ported from
existing code in Safari.

* Source/WebKit/UIProcess/Extensions/Cocoa/_WKWebExtensionDeclarativeNetRequestSQLiteStore.h: Added.
* Source/WebKit/UIProcess/Extensions/Cocoa/_WKWebExtensionDeclarativeNetRequestSQLiteStore.mm: Added.
(-[_WKWebExtensionDeclarativeNetRequestSQLiteStore initWithUniqueIdentifier:directory:usesInMemoryDatabase:]):
(-[_WKWebExtensionDeclarativeNetRequestSQLiteStore updateRulesByRemovingIDs:addRules:completionHandler:]):
(-[_WKWebExtensionDeclarativeNetRequestSQLiteStore addRules:completionHandler:]):
(-[_WKWebExtensionDeclarativeNetRequestSQLiteStore deleteRules:completionHandler:]):
(-[_WKWebExtensionDeclarativeNetRequestSQLiteStore getRulesWithCompletionHandler:]):
(-[_WKWebExtensionDeclarativeNetRequestSQLiteStore _getRulesWithOutErrorMessage:]):
(-[_WKWebExtensionDeclarativeNetRequestSQLiteStore _getKeysAndValuesFromRowEnumerator:]):
(-[_WKWebExtensionDeclarativeNetRequestSQLiteStore _insertRule:inDatabase:]):
(-[_WKWebExtensionDeclarativeNetRequestSQLiteStore _currentDatabaseSchemaVersion]):
(-[_WKWebExtensionDeclarativeNetRequestSQLiteStore _databaseURL]):
(-[_WKWebExtensionDeclarativeNetRequestSQLiteStore _createFreshDatabaseSchema]):
(-[_WKWebExtensionDeclarativeNetRequestSQLiteStore _resetDatabaseSchema]):
(-[_WKWebExtensionDeclarativeNetRequestSQLiteStore _isDatabaseEmpty]):
* Source/WebKit/WebKit.xcodeproj/project.pbxproj:

Canonical link: https://commits.webkit.org/271647@main
  • Loading branch information
b-weinstein committed Dec 7, 2023
1 parent d3069e0 commit b6d6257
Show file tree
Hide file tree
Showing 3 changed files with 351 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (C) 2023 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/

#pragma once

#import "_WKWebExtensionSQLiteStore.h"

NS_ASSUME_NONNULL_BEGIN

@interface _WKWebExtensionDeclarativeNetRequestSQLiteStore : _WKWebExtensionSQLiteStore

- (void)getRulesWithCompletionHandler:(void (^)(NSArray<NSDictionary<NSString *, id> *> *rules, NSString *errorMessage))completionHandler;
- (void)updateRulesByRemovingIDs:(NSArray<NSNumber *> *)ruleIDs addRules:(NSArray<NSDictionary<NSString *, id> *> *)rules completionHandler:(void (^)(NSString *errorMessage))completionHandler;

@end

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
@@ -0,0 +1,304 @@
/*
* Copyright (C) 2023 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/

#if !__has_feature(objc_arc)
#error This file requires ARC. Add the "-fobjc-arc" compiler flag for this file.
#endif

#import "config.h"
#import "_WKWebExtensionDeclarativeNetRequestSQLiteStore.h"

#import "CocoaHelpers.h"
#import "Logging.h"
#import "_WKWebExtensionSQLiteDatabase.h"
#import "_WKWebExtensionSQLiteHelpers.h"
#import "_WKWebExtensionSQLiteRow.h"
#import <wtf/WeakObjCPtr.h>

using namespace WebKit;

#if ENABLE(WK_WEB_EXTENSIONS)

static const SchemaVersion currentDatabaseSchemaVersion = 1;

@implementation _WKWebExtensionDeclarativeNetRequestSQLiteStore {
NSString *_storageType;
NSString *_tableName;
}

- (instancetype)initWithUniqueIdentifier:(NSString *)uniqueIdentifier directory:(NSString *)directory usesInMemoryDatabase:(BOOL)useInMemoryDatabase
{
if (!(self = [super initWithUniqueIdentifier:uniqueIdentifier directory:directory usesInMemoryDatabase:useInMemoryDatabase]))
return nil;

_storageType = _useInMemoryDatabase ? @"session" : @"dynamic";
_tableName = [NSString stringWithFormat:@"%@_rules", _storageType];
return self;
}

- (void)updateRulesByRemovingIDs:(NSArray<NSNumber *> *)ruleIDs addRules:(NSArray<NSDictionary<NSString *, id> *> *)rules completionHandler:(void (^)(NSString *errorMessage))completionHandler
{
auto weakSelf = WeakObjCPtr<_WKWebExtensionDeclarativeNetRequestSQLiteStore> { self };
[self deleteRules:ruleIDs completionHandler:^(NSString *errorMessage) {
auto strongSelf = weakSelf.get();
if (!strongSelf)
return;

if (errorMessage.length) {
completionHandler(errorMessage);
return;
}

[strongSelf addRules:rules completionHandler:^(NSString *errorMessage) {
completionHandler(errorMessage);
}];
}];
}

- (void)addRules:(NSArray<NSDictionary<NSString *, id> *> *)rules completionHandler:(void (^)(NSString *errorMessage))completionHandler
{
if (!rules.count) {
completionHandler(nil);
return;
}

auto weakSelf = WeakObjCPtr<_WKWebExtensionDeclarativeNetRequestSQLiteStore> { self };
dispatch_async(_databaseQueue, ^{
auto strongSelf = weakSelf.get();
if (!strongSelf)
return;

NSString *errorMessage;
if (![strongSelf _openDatabaseIfNecessaryReturningErrorMessage:&errorMessage]) {
dispatch_async(dispatch_get_main_queue(), ^{
completionHandler(errorMessage);
});

return;
}

ASSERT(!errorMessage.length);
ASSERT(strongSelf->_database);

NSMutableArray<NSNumber *> *rulesIDs = [NSMutableArray arrayWithCapacity:rules.count];
for (NSDictionary<NSString *, id> *rule in rules) {
NSNumber *ruleID = objectForKey<NSNumber>(rule, @"id");
ASSERT(ruleID);
[rulesIDs addObject:ruleID];
}

ASSERT(rulesIDs.count);

_WKWebExtensionSQLiteRowEnumerator *rows = SQLiteDatabaseFetch(strongSelf->_database, [NSString stringWithFormat:@"SELECT id FROM %@ WHERE id in (%@)", strongSelf->_tableName, [rulesIDs componentsJoinedByString:@", "]]);

NSMutableArray<NSNumber *> *existingRuleIDs = [NSMutableArray array];
for (_WKWebExtensionSQLiteRow *row in rows)
[existingRuleIDs addObject:[NSNumber numberWithInteger:[row int64AtIndex:0]]];

if (existingRuleIDs.count == 1)
errorMessage = [NSString stringWithFormat:@"Failed to add %@ rules. Rule %@ does not have a unique ID.", strongSelf->_storageType, existingRuleIDs.firstObject];
else if (existingRuleIDs.count >= 2)
errorMessage = [NSString stringWithFormat:@"Failed to add %@ rules. Some rules do not have unique IDs (%@).", strongSelf->_storageType, [existingRuleIDs componentsJoinedByString:@", "]];

if (errorMessage.length) {
dispatch_async(dispatch_get_main_queue(), ^{
completionHandler(errorMessage);
});

return;
}

for (NSDictionary<NSString *, id> *rule in rules) {
errorMessage = [strongSelf _insertRule:rule inDatabase:strongSelf->_database];
if (errorMessage.length)
break;
}

dispatch_async(dispatch_get_main_queue(), ^{
completionHandler(errorMessage);
});
});
}

- (void)deleteRules:(NSArray<NSNumber *> *)ruleIDs completionHandler:(void (^)(NSString *errorMessage))completionHandler
{
if (!ruleIDs.count) {
completionHandler(nil);
return;
}

auto weakSelf = WeakObjCPtr<_WKWebExtensionDeclarativeNetRequestSQLiteStore> { self };
dispatch_async(_databaseQueue, ^{
auto strongSelf = weakSelf.get();
if (!strongSelf)
return;

NSString *errorMessage;
if (![strongSelf _openDatabaseIfNecessaryReturningErrorMessage:&errorMessage]) {
dispatch_async(dispatch_get_main_queue(), ^{
completionHandler(errorMessage);
});

return;
}

ASSERT(!errorMessage.length);
ASSERT(strongSelf->_database);

DatabaseResult result = SQLiteDatabaseExecute(strongSelf->_database, [NSString stringWithFormat:@"DELETE FROM %@ WHERE id in (%@)", strongSelf->_tableName, [ruleIDs componentsJoinedByString:@", "]]);
if (result != SQLITE_DONE) {
RELEASE_LOG_ERROR(Extensions, "Failed to delete rules for extension %{private}@.", strongSelf->_uniqueIdentifier);
errorMessage = [NSString stringWithFormat:@"Failed to delete rules from %@ rules storage.", strongSelf->_storageType];
}

NSString *deleteDatabaseErrorMessage = [strongSelf _deleteDatabaseIfEmpty];

dispatch_async(dispatch_get_main_queue(), ^{
// Errors from opening the database or deleting keys take precedence over an error deleting the database.
completionHandler(errorMessage.length ? errorMessage : deleteDatabaseErrorMessage);
});
});
}

- (void)getRulesWithCompletionHandler:(void (^)(NSArray<NSDictionary<NSString *, id> *> *rules, NSString *errorMessage))completionHandler
{
auto weakSelf = WeakObjCPtr<_WKWebExtensionDeclarativeNetRequestSQLiteStore> { self };
dispatch_async(_databaseQueue, ^{
auto strongSelf = weakSelf.get();
if (!strongSelf)
return;

NSString *errorMessage;
NSArray<NSDictionary<NSString *, id> *> *rules = [strongSelf _getRulesWithOutErrorMessage:&errorMessage];

dispatch_async(dispatch_get_main_queue(), ^{
completionHandler(rules, errorMessage);
});
});
}

- (NSArray<NSDictionary<NSString *, id> *> *)_getRulesWithOutErrorMessage:(NSString **)outErrorMessage
{
dispatch_assert_queue(_databaseQueue);

if (![self _openDatabaseIfNecessaryReturningErrorMessage:outErrorMessage])
return @[ ];

ASSERT(!(*outErrorMessage).length);
ASSERT(_database);

_WKWebExtensionSQLiteRowEnumerator *rows = SQLiteDatabaseFetch(_database, [NSString stringWithFormat:@"SELECT * FROM %@", _tableName]);
return [self _getKeysAndValuesFromRowEnumerator:rows];
}

- (NSArray<NSDictionary<NSString *, id> *> *)_getKeysAndValuesFromRowEnumerator:(_WKWebExtensionSQLiteRowEnumerator *)rows
{
static NSSet *allowedClasses = [NSSet setWithObjects:NSDictionary.class, NSNumber.class, NSString.class, NSArray.class, nil];

NSMutableArray<NSDictionary<NSString *, id> *> *rules = [NSMutableArray array];

for (_WKWebExtensionSQLiteRow *row in rows) {
NSError *error;
NSDictionary<NSString *, id> *rule = [NSKeyedUnarchiver unarchivedObjectOfClasses:allowedClasses fromData:[row dataAtIndex:1] error:&error];

if (error)
RELEASE_LOG_ERROR(Extensions, "Failed to deserialize dynamic declarative net request rule for extension %{private}@.", _uniqueIdentifier);
else
[rules addObject:rule];
}

return rules;
}

- (NSString *)_insertRule:(NSDictionary<NSString *, id> *)rule inDatabase:(_WKWebExtensionSQLiteDatabase *)database
{
dispatch_assert_queue(_databaseQueue);
ASSERT(_database);

NSData *ruleAsData = [NSKeyedArchiver archivedDataWithRootObject:rule requiringSecureCoding:YES error:nil];
NSNumber *ruleID = objectForKey<NSNumber>(rule, @"id");
ASSERT(ruleID);

DatabaseResult result = SQLiteDatabaseExecute(database, [NSString stringWithFormat:@"INSERT INTO %@ (id, rule) VALUES (?, ?)", _tableName], ruleID.integerValue, ruleAsData);
if (result != SQLITE_DONE) {
RELEASE_LOG_ERROR(Extensions, "Failed to insert dynamic declarative net request rule for extension %{private}@.", _uniqueIdentifier);
return [NSString stringWithFormat:@"Failed to add %@ rule.", self->_storageType];
}

return nil;
}

// MARK: Database Schema

- (SchemaVersion)_currentDatabaseSchemaVersion
{
return currentDatabaseSchemaVersion;
}

- (NSURL *)_databaseURL
{
if (_useInMemoryDatabase)
return [_WKWebExtensionSQLiteDatabase inMemoryDatabaseURL];

NSString *databaseName = @"dnr-dynamic-rules.db";
return [_directory URLByAppendingPathComponent:databaseName isDirectory:NO];
}

- (DatabaseResult)_createFreshDatabaseSchema
{
dispatch_assert_queue(_databaseQueue);
ASSERT(_database);

DatabaseResult result = SQLiteDatabaseExecute(_database, [NSString stringWithFormat:@"CREATE TABLE %@ (id INTEGER PRIMARY KEY NOT NULL, rule BLOB NOT NULL)", _tableName]);
if (result != SQLITE_DONE)
RELEASE_LOG_ERROR(Extensions, "Failed to create %@ database for extension %{private}@: %{public}@ (%d)", _tableName, _uniqueIdentifier, _database.lastErrorMessage, result);

return result;
}

- (DatabaseResult)_resetDatabaseSchema
{
dispatch_assert_queue(_databaseQueue);
ASSERT(_database);

DatabaseResult result = SQLiteDatabaseExecute(_database, [NSString stringWithFormat:@"DROP TABLE IF EXISTS %@", _tableName]);
if (result != SQLITE_DONE)
RELEASE_LOG_ERROR(Extensions, "Failed to reset %@ database schema for extension %{private}@: %{public}@ (%d)", _tableName, _uniqueIdentifier, _database.lastErrorMessage, result);

return result;
}

- (BOOL)_isDatabaseEmpty
{
dispatch_assert_queue(_databaseQueue);
ASSERT(_database);

_WKWebExtensionSQLiteRowEnumerator *rows = SQLiteDatabaseFetch(_database, [NSString stringWithFormat:@"SELECT COUNT(*) FROM %@", _tableName]);
return ![[rows nextObject] int64AtIndex:0];
}

@end

#endif // ENABLE(WK_WEB_EXTENSIONS)
8 changes: 8 additions & 0 deletions Source/WebKit/WebKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -909,6 +909,8 @@
3326F2672B06A1F4001A535F /* _WKWebExtensionDeclarativeNetRequestTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = 3326F2632B06A1F4001A535F /* _WKWebExtensionDeclarativeNetRequestTranslator.h */; settings = {ATTRIBUTES = (Private, ); }; };
3326F2682B06A1F4001A535F /* _WKWebExtensionDeclarativeNetRequestTranslator.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3326F2642B06A1F4001A535F /* _WKWebExtensionDeclarativeNetRequestTranslator.mm */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
3336763B130C99DC006C9DE2 /* WKResourceCacheManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 33367639130C99DC006C9DE2 /* WKResourceCacheManager.h */; settings = {ATTRIBUTES = (Private, ); }; };
3343C3262B21140C00AD10A6 /* _WKWebExtensionDeclarativeNetRequestSQLiteStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 3343C3242B21140C00AD10A6 /* _WKWebExtensionDeclarativeNetRequestSQLiteStore.h */; };
3343C3272B21140C00AD10A6 /* _WKWebExtensionDeclarativeNetRequestSQLiteStore.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3343C3252B21140C00AD10A6 /* _WKWebExtensionDeclarativeNetRequestSQLiteStore.mm */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
335698F62B19307700C7FEE4 /* WebExtensionDeclarativeNetRequestConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 335698F52B19307700C7FEE4 /* WebExtensionDeclarativeNetRequestConstants.h */; };
3375A37129429DDA0028536D /* WebExtensionAPIWebNavigationCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3375A37029429DDA0028536D /* WebExtensionAPIWebNavigationCocoa.mm */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
3375A37529429DF50028536D /* WebExtensionAPIWebNavigation.h in Headers */ = {isa = PBXBuildFile; fileRef = 3375A37329429DF50028536D /* WebExtensionAPIWebNavigation.h */; };
Expand Down Expand Up @@ -4672,6 +4674,8 @@
3326F2642B06A1F4001A535F /* _WKWebExtensionDeclarativeNetRequestTranslator.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _WKWebExtensionDeclarativeNetRequestTranslator.mm; sourceTree = "<group>"; };
33367638130C99DC006C9DE2 /* WKResourceCacheManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKResourceCacheManager.cpp; sourceTree = "<group>"; };
33367639130C99DC006C9DE2 /* WKResourceCacheManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKResourceCacheManager.h; sourceTree = "<group>"; };
3343C3242B21140C00AD10A6 /* _WKWebExtensionDeclarativeNetRequestSQLiteStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKWebExtensionDeclarativeNetRequestSQLiteStore.h; sourceTree = "<group>"; };
3343C3252B21140C00AD10A6 /* _WKWebExtensionDeclarativeNetRequestSQLiteStore.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _WKWebExtensionDeclarativeNetRequestSQLiteStore.mm; sourceTree = "<group>"; };
335698F52B19307700C7FEE4 /* WebExtensionDeclarativeNetRequestConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebExtensionDeclarativeNetRequestConstants.h; sourceTree = "<group>"; };
3375A37029429DDA0028536D /* WebExtensionAPIWebNavigationCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebExtensionAPIWebNavigationCocoa.mm; sourceTree = "<group>"; };
3375A37329429DF50028536D /* WebExtensionAPIWebNavigation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebExtensionAPIWebNavigation.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -9221,6 +9225,8 @@
1C1549802926E7CC001B9E5B /* API */,
3326F2622B06A1F4001A535F /* _WKWebExtensionDeclarativeNetRequestRule.h */,
3326F2612B06A1F4001A535F /* _WKWebExtensionDeclarativeNetRequestRule.mm */,
3343C3242B21140C00AD10A6 /* _WKWebExtensionDeclarativeNetRequestSQLiteStore.h */,
3343C3252B21140C00AD10A6 /* _WKWebExtensionDeclarativeNetRequestSQLiteStore.mm */,
3326F2632B06A1F4001A535F /* _WKWebExtensionDeclarativeNetRequestTranslator.h */,
3326F2642B06A1F4001A535F /* _WKWebExtensionDeclarativeNetRequestTranslator.mm */,
1CF0C94F2AC380E900EC82F2 /* WebExtensionActionCocoa.mm */,
Expand Down Expand Up @@ -15031,6 +15037,7 @@
1C3BEB5A28875CE500E66E38 /* _WKWebExtensionControllerInternal.h in Headers */,
1C3BEB5C28875CE500E66E38 /* _WKWebExtensionControllerPrivate.h in Headers */,
3326F2662B06A1F4001A535F /* _WKWebExtensionDeclarativeNetRequestRule.h in Headers */,
3343C3262B21140C00AD10A6 /* _WKWebExtensionDeclarativeNetRequestSQLiteStore.h in Headers */,
3326F2672B06A1F4001A535F /* _WKWebExtensionDeclarativeNetRequestTranslator.h in Headers */,
1C3BEB722888842F00E66E38 /* _WKWebExtensionInternal.h in Headers */,
B68437B329A3E2F500472D1B /* _WKWebExtensionLocalization.h in Headers */,
Expand Down Expand Up @@ -18114,6 +18121,7 @@
1C62747A288B2F7400CED3A2 /* _WKWebExtensionController.mm in Sources */,
1C1549D729381DFF001B9E5B /* _WKWebExtensionControllerConfiguration.mm in Sources */,
3326F2652B06A1F4001A535F /* _WKWebExtensionDeclarativeNetRequestRule.mm in Sources */,
3343C3272B21140C00AD10A6 /* _WKWebExtensionDeclarativeNetRequestSQLiteStore.mm in Sources */,
3326F2682B06A1F4001A535F /* _WKWebExtensionDeclarativeNetRequestTranslator.mm in Sources */,
B62C01BC2A8E7AF600D6A941 /* _WKWebExtensionLocalization.mm in Sources */,
1C1CE972288DF5030098D3A1 /* _WKWebExtensionMatchPattern.mm in Sources */,
Expand Down

0 comments on commit b6d6257

Please sign in to comment.