Skip to content

Revert content-blocker target redistribution and restore extension display names#209

Merged
0xCUB3 merged 1 commit intomainfrom
codex/undo-latest-commit
Jan 25, 2026
Merged

Revert content-blocker target redistribution and restore extension display names#209
0xCUB3 merged 1 commit intomainfrom
codex/undo-latest-commit

Conversation

@0xCUB3
Copy link
Copy Markdown
Owner

@0xCUB3 0xCUB3 commented Jan 25, 2026

Motivation

  • Undo the previous change that split filters across multiple content-blocker targets and renamed extensions to numbered display names.
  • Restore the prior behavior of mapping filters to extensions by category and keep extension names descriptive in the Xcode project.
  • Ensure rule-count tracking and fast-update flows remain compatible with prior protobuf storage and extension mapping.

Description

  • Reverted the redistribution logic and removed helper functions that distributed filters by load (removed distributeFiltersToTargets and targetDisplayName), instead assigning filters using ContentBlockerTargetManager.targetInfo(forCategory:platform:).
  • Simplified conversion and reload flow in AppFilterManager to process filters per target category, update ruleCountsByExtension, and handle rule-limit conditions by resetting affected categories to recommended lists and reprocessing.
  • Updated logging and metadata keys from target names to category/bundleId, and adjusted retry/reload helpers to use targetInfo.primaryCategory.rawValue.
  • Restored extension display names in project build settings (INFOPLIST_KEY_CFBundleDisplayName) and removed the numbered CFBundleDisplayName/CFBundleName entries introduced earlier in several extension Info.plist files.

Testing

  • No automated tests were run on these changes.

Codex Task

…extensions to wBlock 1–5 (#208)"

This reverts commit 5de6f48.
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @0xCUB3, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request reverts a recent change that introduced a complex filter redistribution mechanism across multiple content-blocker targets and assigned generic, numbered display names to extensions. The primary goal is to restore the prior, simpler behavior where filters are mapped to extensions by category, ensuring that extension names are descriptive within the Xcode project. This change also simplifies the filter processing and reloading logic, aiming for better maintainability and compatibility with existing protobuf storage and extension mapping.

Highlights

  • Content Blocker Redistribution Reverted: The previous logic that split content-blocker filters across multiple targets based on load has been undone, restoring the original category-based mapping.
  • Extension Display Names Restored: Numbered display names for extensions (e.g., 'wBlock 1') have been reverted to more descriptive, category-based names (e.g., 'wBlock Ads') in both Info.plist files and the Xcode project settings.
  • Simplified Filter Processing: The filter conversion and reload flow in AppFilterManager has been simplified, removing complex redistribution logic and directly processing filters per target category.
  • Logging and Metadata Updates: Logging and metadata keys have been updated to refer to 'category' or 'bundleId' instead of generic 'target' names for better clarity.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@0xCUB3 0xCUB3 merged commit 3449a35 into main Jan 25, 2026
2 checks passed
@0xCUB3 0xCUB3 deleted the codex/undo-latest-commit branch January 25, 2026 23:28
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request effectively reverts the previous content-blocker target redistribution logic and restores descriptive display names for extensions. The changes simplify the filter application process by mapping filters to extensions based on their category, which is a welcome improvement for maintainability. The updates to the Xcode project and Info.plist files correctly restore the human-readable names.

I've identified a couple of areas for improvement. Firstly, there appears to be a misconfiguration in the Xcode project file for the 'wBlock Privacy' macOS target, which I've flagged as a high-severity issue. Secondly, the new logic for handling rule-limit overflows in AppFilterManager could be made more memory-efficient and less duplicative by reusing an existing helper function. My review includes a suggestion for this refactoring. Addressing these points will improve the correctness and robustness of the implementation.

GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "wBlock Ads/Info.plist";
INFOPLIST_KEY_CFBundleDisplayName = "wBlock 2";
INFOPLIST_KEY_CFBundleDisplayName = "wBlock Privacy";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

While you're correctly updating the display name to be descriptive, it seems the wBlock Privacy target (for macOS) is incorrectly configured to use the Info.plist from the wBlock Ads target (see line 2831: INFOPLIST_FILE = "wBlock Ads/Info.plist";).

This is likely a copy-paste error and could lead to incorrect bundle information for the Privacy extension on macOS. Each target should have its own Info.plist file. Please verify and correct the INFOPLIST_FILE path for this target.

GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "wBlock Ads/Info.plist";
INFOPLIST_KEY_CFBundleDisplayName = "wBlock 2";
INFOPLIST_KEY_CFBundleDisplayName = "wBlock Privacy";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Similar to the Debug configuration, the wBlock Privacy target's Release configuration also seems to be pointing to the wrong Info.plist file (wBlock Ads/Info.plist on line 2863). This should be corrected to use a plist specific to the Privacy target to ensure correct bundle information in release builds.

Comment on lines +1076 to +1116
// Re-process this target with the reset filters - on background thread
let disabledSites = self.dataManager.disabledSites
let resetResult = await Task.detached {
let containerURL = await MainActor.run { self.loader.getSharedContainerURL() }
var resetRulesChunks: [String] = []

// Auto-reset categories assigned to this target and warn the user
let affectedCategories = categoriesForTarget.filter { $0 != .all }
for category in affectedCategories {
await resetCategoryToRecommended(category)
// Get the updated filter list after reset
let updatedSelectedFilters = await MainActor.run {
self.filterLists.filter { $0.isSelected }
}

await MainActor.run {
self.showTargetWarning(targetName: targetDisplayName(for: targetInfo), categories: affectedCategories)
self.showingAutoDisabledAlert = true
resetRulesChunks.reserveCapacity(updatedSelectedFilters.count)

for filter in updatedSelectedFilters {
if filter.category == targetInfo.primaryCategory
|| (targetInfo.secondaryCategory != nil
&& filter.category == targetInfo.secondaryCategory!)
{
guard let containerURL = containerURL else { continue }
let fileURL = containerURL.appendingPathComponent(
self.loader.filename(for: filter)
)
if FileManager.default.fileExists(atPath: fileURL.path) {
do {
resetRulesChunks.append(try String(contentsOf: fileURL, encoding: .utf8))
} catch {
await ConcurrentLogManager.shared.error(
.filterApply, "Error reading filter after reset",
metadata: ["filter": filter.name, "error": "\(error)"])
}
}
}
}
await ConcurrentLogManager.shared.info(
.filterApply, "Auto-reset categories due to rule limit exceeded",
metadata: ["target": targetDisplayName(for: targetInfo)])

didRedistribute = true
break
let resetRulesString = resetRulesChunks.joined(separator: "\n")
return ContentBlockerService.convertFilter(
rules: resetRulesString.isEmpty ? "[]" : resetRulesString,
groupIdentifier: GroupIdentifier.shared.value,
targetRulesFilename: targetInfo.rulesFilename,
disabledSites: disabledSites
)
}.value
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The logic to re-process filters after a rule limit is exceeded duplicates functionality from convertFiltersMemoryEfficient but in a less memory-safe way. It reads all filter files into an in-memory string (resetRulesString), which defeats the purpose of the memory-efficient streaming approach used elsewhere.

This could be refactored to reuse convertFiltersMemoryEfficient for better maintainability and to avoid potential memory issues with large filter lists. You can get the updated list of filters for the current target and pass them to convertFiltersMemoryEfficient.

                // Re-process this target with the reset filters.
                let disabledSites = self.dataManager.disabledSites
                let updatedFiltersForTarget = await MainActor.run {
                    self.filterLists.filter {
                        guard $0.isSelected else { return false }
                        let filterTargetInfo = ContentBlockerTargetManager.shared.targetInfo(
                            forCategory: $0.category,
                            platform: self.currentPlatform
                        )
                        return filterTargetInfo?.bundleIdentifier == targetInfo.bundleIdentifier
                    }
                }

                let resetResult = await Task.detached {
                    return await self.convertFiltersMemoryEfficient(
                        filters: updatedFiltersForTarget,
                        targetInfo: targetInfo,
                        disabledSites: disabledSites
                    )
                }.value

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ee942a4150

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1130 to 1134
await MainActor.run {
self.ruleCountsByExtension[targetInfo.bundleIdentifier] = resetRuleCount
self.extensionsApproachingLimit.remove(targetInfo.bundleIdentifier)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Re-check rule limit after auto-reset

After the auto-reset path, the new resetRuleCount is accepted and the “approaching limit” flag is cleared without verifying it actually fell below the 150k limit. If the recommended lists (plus disabled-site rules) still exceed the limit, the app will proceed as if the rules are valid and may attempt reloads that Safari will reject or silently drop, leaving users with a broken blocker but no error. Consider re-validating resetRuleCount against ruleLimit (and re-setting extensionsApproachingLimit accordingly) or aborting with a user-visible error when the reset is still over limit.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant