diff --git a/Package.swift b/Package.swift index 4915f74ff86..0bbcf7bd11e 100644 --- a/Package.swift +++ b/Package.swift @@ -288,7 +288,6 @@ var package = Package( .copy("Resources/duckduckgo-search-plugin.xml"), .copy("Resources/ad-block-resources/resources.json"), .copy("Resources/filter-rules/cdbbhgbmjhfnhnmgeddbliobbofkgdhe.txt"), - .copy("Resources/filter-rules/cffkpbalmllkdoenhmdmpbkajipdjfam.dat"), .copy("Resources/html/index.html"), .copy("Resources/scripts/farbling-tests.js"), .copy("Resources/scripts/request-blocking-tests.js"), diff --git a/Sources/Brave/Frontend/Browser/Helpers/LaunchHelper.swift b/Sources/Brave/Frontend/Browser/Helpers/LaunchHelper.swift index 1e9985d0600..0fde7b93212 100644 --- a/Sources/Brave/Frontend/Browser/Helpers/LaunchHelper.swift +++ b/Sources/Brave/Frontend/Browser/Helpers/LaunchHelper.swift @@ -87,27 +87,6 @@ public actor LaunchHelper { let remainingModes = ContentBlockerManager.BlockingMode.allCases.filter({ !loadedBlockModes.contains($0) }) Task.detached(priority: .low) { - // Let's disable filter lists if we have reached a maxumum amount - let enabledSources = await AdBlockStats.shared.enabledPrioritizedSources - - if enabledSources.count > AdBlockStats.maxNumberOfAllowedFilterLists { - let toDisableSources = enabledSources[AdBlockStats.maxNumberOfAllowedFilterLists...] - - for source in toDisableSources { - switch source { - case .adBlock: - // This should never be in the list because the order of enabledSources places this as the first item - continue - case .filterList(let componentId): - ContentBlockerManager.log.debug("Disabling filter list \(source.debugDescription)") - await FilterListStorage.shared.ensureFilterList(for: componentId, isEnabled: false) - case .filterListURL(let uuid): - ContentBlockerManager.log.debug("Disabling custom filter list \(source.debugDescription)") - await CustomFilterListStorage.shared.ensureFilterList(for: uuid, isEnabled: false) - } - } - } - let signpostID = Self.signpost.makeSignpostID() let state = Self.signpost.beginInterval("nonBlockingLaunchTask", id: signpostID) await FilterListResourceDownloader.shared.start(with: adBlockService) @@ -135,7 +114,7 @@ public actor LaunchHelper { .validBlocklistTypes // All generic types .union( - ContentBlockerManager.GenericBlocklistType.allCases.map { .generic($0) } + ContentBlockerManager.BlocklistType.allStaticTypes ) // All custom filter list urls .union( diff --git a/Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/FilterLists/FilterListsView.swift b/Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/FilterLists/FilterListsView.swift index 91d3bdbdf28..d31ef04f723 100644 --- a/Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/FilterLists/FilterListsView.swift +++ b/Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/FilterLists/FilterListsView.swift @@ -19,10 +19,6 @@ struct FilterListsView: View { @State private var expectedEnabledSources: Set = Set(AdBlockStats.shared.enabledSources) private let dateFormatter = RelativeDateTimeFormatter() - private var reachedMaxLimit: Bool { - expectedEnabledSources.count >= AdBlockStats.maxNumberOfAllowedFilterLists - } - var body: some View { List { Section { @@ -85,7 +81,6 @@ struct FilterListsView: View { .foregroundColor(Color(.secondaryBraveLabel)) } } - .disabled(!filterList.isEnabled && reachedMaxLimit) .onChange(of: filterList.isEnabled) { isEnabled in if isEnabled { expectedEnabledSources.insert(filterList.engineSource) @@ -124,7 +119,6 @@ struct FilterListsView: View { } } } - .disabled(reachedMaxLimit && !filterListURL.setting.isEnabled) .onChange(of: filterListURL.setting.isEnabled) { isEnabled in if isEnabled { expectedEnabledSources.insert(filterListURL.setting.engineSource) diff --git a/Sources/Brave/WebFilters/ContentBlocker/ContentBlockerManager.swift b/Sources/Brave/WebFilters/ContentBlocker/ContentBlockerManager.swift index c47e2a38259..73597330064 100644 --- a/Sources/Brave/WebFilters/ContentBlocker/ContentBlockerManager.swift +++ b/Sources/Brave/WebFilters/ContentBlocker/ContentBlockerManager.swift @@ -80,6 +80,12 @@ actor ContentBlockerManager { fileprivate static let filterListPrefix = "filter-list" fileprivate static let filterListURLPrefix = "filter-list-url" + /// These are all types that are non-configurable by the user + /// and don't need additional stored or fetched catalogues to get a complete list. + static var allStaticTypes: Set { + return Set(ContentBlockerManager.GenericBlocklistType.allCases.map { .generic($0) }) + } + case generic(GenericBlocklistType) case filterList(componentId: String, isAlwaysAggressive: Bool) case customFilterList(uuid: String) diff --git a/Sources/Brave/WebFilters/FilterListCustomURLDownloader.swift b/Sources/Brave/WebFilters/FilterListCustomURLDownloader.swift index abbbd52ba62..1384811df5f 100644 --- a/Sources/Brave/WebFilters/FilterListCustomURLDownloader.swift +++ b/Sources/Brave/WebFilters/FilterListCustomURLDownloader.swift @@ -89,7 +89,7 @@ actor FilterListCustomURLDownloader: ObservableObject { let uuid = await filterListCustomURL.setting.uuid // Add/remove the resource depending on if it is enabled/disabled - guard let resourcesInfo = await FilterListResourceDownloader.shared.resourcesInfo else { + guard let resourcesInfo = await AdBlockStats.shared.resourcesInfo else { assertionFailure("This should not have been called if the resources are not ready") return } diff --git a/Sources/Brave/WebFilters/FilterListResourceDownloader.swift b/Sources/Brave/WebFilters/FilterListResourceDownloader.swift index 95f7e174bb2..6d7df2fdca4 100644 --- a/Sources/Brave/WebFilters/FilterListResourceDownloader.swift +++ b/Sources/Brave/WebFilters/FilterListResourceDownloader.swift @@ -26,8 +26,6 @@ public actor FilterListResourceDownloader { /// A marker that says that we loaded shield components for the first time. /// This boolean is used to configure this downloader only once after `AdBlockService` generic shields have been loaded. private var registeredFilterLists = false - /// The path to the resources file - private(set) var resourcesInfo: CachedAdBlockEngine.ResourcesInfo? init() { self.adBlockServiceTasks = [:] @@ -40,27 +38,37 @@ public actor FilterListResourceDownloader { /// - Warning: This method loads filter list settings. /// You need to wait for `DataController.shared.initializeOnce()` to be called first before invoking this method public func loadFilterListSettingsAndCachedData() async { - if let defaultFilterListFolderURL = await FilterListSetting.makeFolderURL( - forFilterListFolderPath: Preferences.AppState.lastFilterListCatalogueComponentFolderPath.value - ), FileManager.default.fileExists(atPath: defaultFilterListFolderURL.path), - let resourcesFolderURL = await FilterListSetting.makeFolderURL( - forFilterListFolderPath: Preferences.AppState.lastAdBlockResourcesFolderPath.value - ), FileManager.default.fileExists(atPath: resourcesFolderURL.path) { - let resourcesInfo = await didUpdateResourcesComponent(folderURL: resourcesFolderURL) - async let startedCustomFilterListsDownloader: Void = FilterListCustomURLDownloader.shared.startIfNeeded() - async let cachedFilterLists: Void = compileCachedFilterLists(resourcesInfo: resourcesInfo) - async let compileDefaultEngine: Void = compileDefaultEngine(defaultFilterListFolderURL: defaultFilterListFolderURL, resourcesInfo: resourcesInfo) - _ = await (startedCustomFilterListsDownloader, cachedFilterLists, compileDefaultEngine) - } else if let legacyComponentFolderURL = await FilterListSetting.makeFolderURL( - forFilterListFolderPath: Preferences.AppState.lastLegacyDefaultFilterListFolderPath.value - ), FileManager.default.fileExists(atPath: legacyComponentFolderURL.path) { - // TODO: @JS Remove this after this release. Its here just so users can upgrade without a pause to their adblocking - let resourcesInfo = await didUpdateResourcesComponent(folderURL: legacyComponentFolderURL) - async let startedCustomFilterListsDownloader: Void = FilterListCustomURLDownloader.shared.startIfNeeded() - async let cachedFilterLists: Void = compileCachedFilterLists(resourcesInfo: resourcesInfo) - async let compileDefaultEngine: Void = compileDefaultEngine(defaultFilterListFolderURL: legacyComponentFolderURL, resourcesInfo: resourcesInfo) - _ = await (startedCustomFilterListsDownloader, cachedFilterLists, compileDefaultEngine) + guard let resourcesFolderURL = await FilterListSetting.makeFolderURL( + forComponentFolderPath: Preferences.AppState.lastAdBlockResourcesFolderPath.value + ), FileManager.default.fileExists(atPath: resourcesFolderURL.path) else { + // We need this for all filter lists so we can't compile anything until we download it + return + } + + let resourcesInfo = await didUpdateResourcesComponent(folderURL: resourcesFolderURL) + async let startedCustomFilterListsDownloader: Void = FilterListCustomURLDownloader.shared.startIfNeeded() + async let cachedFilterLists: Void = compileCachedFilterLists(resourcesInfo: resourcesInfo) + async let compileDefaultEngine: Void = compileDefaultFilterList(resourcesInfo: resourcesInfo) + + _ = await (startedCustomFilterListsDownloader, cachedFilterLists, compileDefaultEngine) + } + + /// Compile the default filter list from cache + private func compileDefaultFilterList(resourcesInfo: CachedAdBlockEngine.ResourcesInfo) async { + guard let defaultFilterListFolderURL = await FilterListSetting.makeFolderURL( + forComponentFolderPath: Preferences.AppState.lastFilterListCatalogueComponentFolderPath.value + ), FileManager.default.fileExists(atPath: defaultFilterListFolderURL.path) else { + // We don't really need this but its the most important filter list + // so without this not much point compiling anything else because we probably don't have it + return } + + await compileEngine( + filterListFolderURL: defaultFilterListFolderURL, resourcesInfo: resourcesInfo, + engineSource: .adBlock, isAlwaysAggressive: false, + // This is false because we use a slim-list version of the list downloaded from S3 + compileContentBlockers: false + ) } /// This function adds engine resources to `AdBlockManager` from cached data representing the enabled filter lists. @@ -106,7 +114,11 @@ public actor FilterListResourceDownloader { public func start(with adBlockService: AdblockService) { self.adBlockService = adBlockService - // Start listening to changes to the install url + // This is somewhat tricky: + // 1. All our filter lists need the resources component. So we register this first + // 2. We also register the catalogue component since we don't need the resources for this + // 3. When either of the above triggers we check if we have our resources and catalogue and + // register all of the filter lists Task { @MainActor in for await folderURL in adBlockService.resourcesComponentStream() { guard let folderURL = folderURL else { @@ -127,7 +139,7 @@ public actor FilterListResourceDownloader { for await filterListEntries in adBlockService.filterListCatalogComponentStream() { FilterListStorage.shared.loadFilterLists(from: filterListEntries) - if await self.resourcesInfo != nil { + if await AdBlockStats.shared.resourcesInfo != nil { await registerAllFilterListsIfNeeded(with: adBlockService) } } @@ -156,12 +168,16 @@ public actor FilterListResourceDownloader { } await Task { @MainActor in - let folderSubPath = FilterListSetting.extractFolderPath(fromFilterListFolderURL: folderURL) + let folderSubPath = FilterListSetting.extractFolderPath(fromComponentFolderURL: folderURL) Preferences.AppState.lastFilterListCatalogueComponentFolderPath.value = folderSubPath }.value - if let resourcesInfo = await self.resourcesInfo { - await compileDefaultEngine(defaultFilterListFolderURL: folderURL, resourcesInfo: resourcesInfo) + if let resourcesInfo = await AdBlockStats.shared.resourcesInfo { + await compileEngine( + filterListFolderURL: folderURL, resourcesInfo: resourcesInfo, + engineSource: .adBlock, isAlwaysAggressive: false, + compileContentBlockers: false // This is set to false because we unfortunately have to use the slim list version of these lists + ) } } } @@ -171,7 +187,7 @@ public actor FilterListResourceDownloader { /// When the private func didUpdateResourcesComponent(folderURL: URL) async -> CachedAdBlockEngine.ResourcesInfo { await Task { @MainActor in - let folderSubPath = FilterListSetting.extractFolderPath(fromFilterListFolderURL: folderURL) + let folderSubPath = FilterListSetting.extractFolderPath(fromComponentFolderURL: folderURL) Preferences.AppState.lastAdBlockResourcesFolderPath.value = folderSubPath }.value @@ -181,29 +197,31 @@ public actor FilterListResourceDownloader { version: version ) - self.resourcesInfo = resourcesInfo + await AdBlockStats.shared.updateIfNeeded(resourcesInfo: resourcesInfo) return resourcesInfo } - /// Compile the general engine from the given `AdblockService` `shieldsInstallPath` `URL`. - private func compileDefaultEngine(defaultFilterListFolderURL folderURL: URL, resourcesInfo: CachedAdBlockEngine.ResourcesInfo) async { - // TODO: @JS Remove this on the next update. This is here so users don't have a pause to their ad-blocking - let isLegacy = folderURL.pathExtension == "dat" - let localFileURL = isLegacy ? folderURL.appendingPathComponent("rs-ABPFilterParserData.dat", conformingTo: .data) : folderURL.appendingPathComponent("list.txt", conformingTo: .text) + /// Compile the engine from the given `AdblockService` `shieldsInstallPath` `URL`. + private func compileEngine( + filterListFolderURL folderURL: URL, resourcesInfo: CachedAdBlockEngine.ResourcesInfo, + engineSource: CachedAdBlockEngine.Source, + isAlwaysAggressive: Bool, compileContentBlockers: Bool + ) async { + let localFileURL = folderURL.appendingPathComponent("list.txt", conformingTo: .text) let version = folderURL.lastPathComponent let filterListInfo = CachedAdBlockEngine.FilterListInfo( - source: .adBlock, + source: engineSource, localFileURL: localFileURL, - version: version, fileType: isLegacy ? .dat : .text + version: version, fileType: .text ) let lazyInfo = AdBlockStats.LazyFilterListInfo( - filterListInfo: filterListInfo, isAlwaysAggressive: false + filterListInfo: filterListInfo, isAlwaysAggressive: isAlwaysAggressive ) await AdBlockStats.shared.compile( lazyInfo: lazyInfo, resourcesInfo: resourcesInfo, - compileContentBlockers: false + compileContentBlockers: compileContentBlockers ) } @@ -253,7 +271,7 @@ public actor FilterListResourceDownloader { adBlockServiceTasks[filterList.entry.componentId] = Task { @MainActor in for await folderURL in adBlockService.register(filterList: filterList) { guard let folderURL = folderURL else { continue } - guard let resourcesInfo = await self.resourcesInfo else { + guard let resourcesInfo = await AdBlockStats.shared.resourcesInfo else { assertionFailure("We shouldn't have started downloads before getting this value") return } diff --git a/Sources/Brave/WebFilters/ShieldStats/Adblock/AdBlockEngine+Extensions.swift b/Sources/Brave/WebFilters/ShieldStats/Adblock/AdBlockEngine+Extensions.swift index 2ad3cf11cba..90bdb1c980c 100644 --- a/Sources/Brave/WebFilters/ShieldStats/Adblock/AdBlockEngine+Extensions.swift +++ b/Sources/Brave/WebFilters/ShieldStats/Adblock/AdBlockEngine+Extensions.swift @@ -18,16 +18,6 @@ extension AdblockEngine { try useResources(fromFileURL: resourcesFileURL) } - convenience init(datFileURL fileURL: URL, resourcesFileURL: URL) throws { - self.init() - - if try !deserialize(data: Data(contentsOf: fileURL)) { - throw CompileError.couldNotDeserializeDATFile - } - - try useResources(fromFileURL: resourcesFileURL) - } - /// Combine all resources of type rule lists to one single string private static func combineAllRuleLists(from infos: [CachedAdBlockEngine.FilterListInfo]) -> String { // Combine all rule lists that need to be injected during initialization @@ -39,8 +29,6 @@ extension AdblockEngine { } return String(data: data, encoding: .utf8) - case .dat: - return nil } } diff --git a/Sources/Brave/WebFilters/ShieldStats/Adblock/AdBlockStats.swift b/Sources/Brave/WebFilters/ShieldStats/Adblock/AdBlockStats.swift index 58c52f962e3..20e473cf14d 100644 --- a/Sources/Brave/WebFilters/ShieldStats/Adblock/AdBlockStats.swift +++ b/Sources/Brave/WebFilters/ShieldStats/Adblock/AdBlockStats.swift @@ -11,16 +11,6 @@ import os.log /// This object holds on to our adblock engines and returns information needed for stats tracking as well as some conveniences /// for injected scripts needed during web navigation and cosmetic filters models needed by the `SelectorsPollerScript.js` script. public actor AdBlockStats { - /// The max number of enabled filter lists depending on the amount memory available to the device - static var maxNumberOfAllowedFilterLists: Int = { - // Get the number of gigs (memory in bytes divided by the size of a gig in bytes) - let numberOfGigs = Int(ProcessInfo.processInfo.physicalMemory / 1073741824) - ContentBlockerManager.log.debug("Number of gigs (rounded down): \(numberOfGigs)") - // Take a value between 20 and 40, - // with the real value somewhere in the middle depending on the device's memory - return max(min(5 * numberOfGigs, 40), 20) - }() - typealias CosmeticFilterModelTuple = (isAlwaysAggressive: Bool, model: CosmeticFilterModel) public static let shared = AdBlockStats() @@ -33,7 +23,7 @@ public actor AdBlockStats { /// A list of filter list info that are available for compilation. This information is used for lazy loading. private(set) var availableFilterLists: [CachedAdBlockEngine.Source: LazyFilterListInfo] /// The info for the resource file. This is a shared file used by all filter lists that contain scriplets. This information is used for lazy loading. - private(set) var resourcesInfo: CachedAdBlockEngine.ResourcesInfo? + public private(set) var resourcesInfo: CachedAdBlockEngine.ResourcesInfo? /// Adblock engine for general adblock lists. private(set) var cachedEngines: [CachedAdBlockEngine.Source: CachedAdBlockEngine] /// The current task that is compiling. @@ -45,31 +35,18 @@ public actor AdBlockStats { /// Used for memory managment so we know which filter lists to disable upon a memory warning @MainActor var criticalSources: [CachedAdBlockEngine.Source] { var enabledSources: [CachedAdBlockEngine.Source] = [.adBlock] - enabledSources.append(contentsOf: FilterListStorage.shared.ciriticalSources) + enabledSources.append(contentsOf: FilterListStorage.shared.criticalSources) return enabledSources } + /// Return an array of all sources that are enabled according to user's settings + /// - Note: This does not take into account the domain or global adblock toggle @MainActor var enabledSources: [CachedAdBlockEngine.Source] { var enabledSources: [CachedAdBlockEngine.Source] = [.adBlock] enabledSources.append(contentsOf: FilterListStorage.shared.enabledSources) enabledSources.append(contentsOf: CustomFilterListStorage.shared.enabledSources) return enabledSources } - - @MainActor var enabledPrioritizedSources: [CachedAdBlockEngine.Source] { - let criticalSources = Set(self.criticalSources) - var enabledSources: [CachedAdBlockEngine.Source] = [.adBlock] - enabledSources.append(contentsOf: FilterListStorage.shared.enabledSources.sorted { left, right in - return criticalSources.contains(left) && !criticalSources.contains(right) - }) - enabledSources.append(contentsOf: CustomFilterListStorage.shared.enabledSources) - return enabledSources - } - - /// Tells us if we reached the max limit of already compiled filter lists - var reachedMaxLimit: Bool { - return cachedEngines.count >= Self.maxNumberOfAllowedFilterLists - } init() { cachedEngines = [:] @@ -88,16 +65,11 @@ public actor AdBlockStats { /// - Note: This method will ensure syncronous compilation public func compile( lazyInfo: LazyFilterListInfo, resourcesInfo: CachedAdBlockEngine.ResourcesInfo, - ignoreMaximum: Bool = false, compileContentBlockers: Bool + compileContentBlockers: Bool ) async { await currentCompileTask?.value currentCompileTask = Task { - if !ignoreMaximum && reachedMaxLimit && cachedEngines[lazyInfo.filterListInfo.source] == nil { - ContentBlockerManager.log.error("Failed to compile engine for \(lazyInfo.filterListInfo.source.debugDescription): Reached maximum!") - return - } - // Compile engine if needsCompilation(for: lazyInfo.filterListInfo, resourcesInfo: resourcesInfo) { do { @@ -186,7 +158,7 @@ public actor AdBlockStats { /// Remove all engines that have disabled sources func ensureEnabledEngines() async { do { - for source in await enabledPrioritizedSources { + for source in await enabledSources { guard cachedEngines[source] == nil else { continue } guard let availableFilterList = availableFilterLists[source] else { continue } guard let resourcesInfo = self.resourcesInfo else { continue } @@ -210,8 +182,8 @@ public actor AdBlockStats { /// Eagerness is determined by several factors: /// * If the source represents a fitler list or a custom filter list, it is eager if it is enabled /// * If the source represents the `adblock` default filter list, it is always eager regardless of shield settings - func isEagerlyLoaded(source: CachedAdBlockEngine.Source) async -> Bool { - return await enabledSources.contains(source) + @MainActor func isEagerlyLoaded(source: CachedAdBlockEngine.Source) -> Bool { + return enabledSources.contains(source) } /// Tells us if an engine needs compilation if it's missing or if its resources are outdated @@ -307,7 +279,7 @@ private extension FilterListStorage { /// /// Critical filter lists are those that are enabled and are "on" by default. Giving us the most important filter lists. /// Used for memory managment so we know which filter lists to disable upon a memory warning - @MainActor var ciriticalSources: [CachedAdBlockEngine.Source] { + @MainActor var criticalSources: [CachedAdBlockEngine.Source] { return enabledSources.filter { source in switch source { case .filterList(let componentId): diff --git a/Sources/Brave/WebFilters/ShieldStats/Adblock/CachedAdBlockEngine.swift b/Sources/Brave/WebFilters/ShieldStats/Adblock/CachedAdBlockEngine.swift index 67306e8be30..65125beb07c 100644 --- a/Sources/Brave/WebFilters/ShieldStats/Adblock/CachedAdBlockEngine.swift +++ b/Sources/Brave/WebFilters/ShieldStats/Adblock/CachedAdBlockEngine.swift @@ -26,11 +26,10 @@ public class CachedAdBlockEngine { } public enum FileType: Hashable, CustomDebugStringConvertible { - case dat, text + case text public var debugDescription: String { switch self { - case .dat: return "dat" case .text: return "txt" } } @@ -201,13 +200,6 @@ public class CachedAdBlockEngine { filterListInfo: FilterListInfo, resourcesInfo: ResourcesInfo, isAlwaysAggressive: Bool ) throws -> CachedAdBlockEngine { switch filterListInfo.fileType { - case .dat: - let engine = try AdblockEngine(datFileURL: filterListInfo.localFileURL, resourcesFileURL: resourcesInfo.localFileURL) - let serialQueue = DispatchQueue(label: "com.brave.WrappedAdBlockEngine.\(UUID().uuidString)") - return CachedAdBlockEngine( - engine: engine, filterListInfo: filterListInfo, resourcesInfo: resourcesInfo, - serialQueue: serialQueue, isAlwaysAggressive: isAlwaysAggressive - ) case .text: let engine = try AdblockEngine(textFileURL: filterListInfo.localFileURL, resourcesFileURL: resourcesInfo.localFileURL) let serialQueue = DispatchQueue(label: "com.brave.WrappedAdBlockEngine.\(UUID().uuidString)") diff --git a/Sources/Data/models/FilterListSetting.swift b/Sources/Data/models/FilterListSetting.swift index c6de8459a2d..8a1df6b188e 100644 --- a/Sources/Data/models/FilterListSetting.swift +++ b/Sources/Data/models/FilterListSetting.swift @@ -25,11 +25,11 @@ public final class FilterListSetting: NSManagedObject, CRUD { @MainActor public var folderURL: URL? { get { - return Self.makeFolderURL(forFilterListFolderPath: folderPath) + return Self.makeFolderURL(forComponentFolderPath: folderPath) } set { // We need to extract the path. We don't want to store the full URL - self.folderPath = Self.extractFolderPath(fromFilterListFolderURL: newValue) + self.folderPath = Self.extractFolderPath(fromComponentFolderURL: newValue) } } @@ -98,13 +98,17 @@ public final class FilterListSetting: NSManagedObject, CRUD { return NSEntityDescription.entity(forEntityName: "FilterListSetting", in: context)! } - public static func makeFolderURL(forFilterListFolderPath folderPath: String?) -> URL? { + /// Since the folder changes upon relaunches we cannot store the whole folder but the path. + /// Here we re-construct the actual folder + public static func makeFolderURL(forComponentFolderPath folderPath: String?) -> URL? { // Combine the path with the base URL guard let folderPath = folderPath else { return nil } return filterListBaseFolderURL?.appendingPathComponent(folderPath) } - public static func extractFolderPath(fromFilterListFolderURL folderURL: URL?) -> String? { + /// Since the folder changes upon relaunches we cannot store the whole folder but the path. + /// Here we extract the path from the folder URL for storage + public static func extractFolderPath(fromComponentFolderURL folderURL: URL?) -> String? { guard let baseURL = filterListBaseFolderURL, let folderURL = folderURL else { return nil } diff --git a/Tests/ClientTests/Resources/filter-rules/cffkpbalmllkdoenhmdmpbkajipdjfam.dat b/Tests/ClientTests/Resources/filter-rules/cffkpbalmllkdoenhmdmpbkajipdjfam.dat deleted file mode 100644 index f804e2b3266..00000000000 Binary files a/Tests/ClientTests/Resources/filter-rules/cffkpbalmllkdoenhmdmpbkajipdjfam.dat and /dev/null differ diff --git a/Tests/ClientTests/Web Filters/CachedAdBlockEngineTests.swift b/Tests/ClientTests/Web Filters/CachedAdBlockEngineTests.swift index c4657bc375e..f69b84eecda 100644 --- a/Tests/ClientTests/Web Filters/CachedAdBlockEngineTests.swift +++ b/Tests/ClientTests/Web Filters/CachedAdBlockEngineTests.swift @@ -87,11 +87,6 @@ final class CachedAdBlockEngineTests: XCTestCase { localFileURL: Bundle.module.url(forResource: "cdbbhgbmjhfnhnmgeddbliobbofkgdhe", withExtension: "txt")!, version: "bundled", fileType: .text ) - let datFilterListInfo = CachedAdBlockEngine.FilterListInfo( - source: .adBlock, - localFileURL: Bundle.module.url(forResource: "cffkpbalmllkdoenhmdmpbkajipdjfam", withExtension: "dat")!, - version: "bundled", fileType: .dat - ) let resourcesInfo = CachedAdBlockEngine.ResourcesInfo( localFileURL: Bundle.module.url(forResource: "resources", withExtension: "json")!, version: "bundled" ) @@ -101,7 +96,7 @@ final class CachedAdBlockEngineTests: XCTestCase { Task { @MainActor in let filterListInfos = [ - textFilterListInfo, datFilterListInfo + textFilterListInfo ] await filterListInfos.asyncConcurrentForEach { filterListInfo in @@ -123,7 +118,7 @@ final class CachedAdBlockEngineTests: XCTestCase { // We should have no scripts injected XCTAssertEqual(sameDomainTypes.count, 0) - if engine.filterListInfo == datFilterListInfo { + if engine.filterListInfo == textFilterListInfo { // This engine file contains some scriplet rules so we can test this part is working let crossDomainTypes = try await engine.makeEngineScriptTypes( frameURL: URL(string: "https://reddit.com")!, isMainFrame: true, domain: domain, index: 0