Skip to content

Pre-processor directives for filters #917

Closed
@ameshkov

Description

@ameshkov

Based on this discussion:
gorhill/uBlock#3331

We should provide multiple pre-processor directives that can be used by filters maintainers to improve compatibility with different ad blockers.

Syntax

!#if condition
Anything goes here
!#include URL_or_a_relative_path
!#endif
  • !#if, !#endif -- filters maintainers can use these conditions to supply different rules depending on the ad blocker type.
  • condition -- just like in some popular programming languages, pre-processor conditions are based on constants declared by ad blockers. Ad blocker authors define on their own what exact constants do they declare.
  • !#include -- this directive allows to include contents of a specified file into the filter.

Conditions

When an adblocker encounters an !#if directive, followed eventually by an !#endif directive, it will compile the code between the directives only if the specified condition is true. Condition supports all the basic logical operators.

Example:

!#if (adguard && !adguard_ext_safari)
||example.org^$third-party
!#endif

Including a file

The !#include directive supports only files from the same origin to make sure that the filter maintainer is in control of the specified file. The included file can also contain pre-processor directives (even other !#include directives).

Ad blockers should consider the case of recursive !#include and implement a protection mechanism.

Examples

Filter URL: https://example.org/path/filter.txt

!
! Valid (same origin):
!#include https://example.org/path/includedfile.txt
!
! Valid (relative path):
!#include /includedfile.txt
!#include ../path2/includedfile.txt
!
! Invalid (another origin):
!#include https://example.com/path/includedfile.txt

Remarks

  • If included file is not found or unavailable, the whole filter update should fail.
  • A conditional directive beginning with a #if directive must explicitly be terminated with a #endif directive.
  • Whitespaces matter. !#if is a valid directive, while !# if is not.

AdGuard-specific

  • Any mistake in a pre-processor directive will lead to AdGuard failing the filter update in the same way as if the filter URL was unavailable.
  • Pre-processor directives can be used in the user filter (or in the custom local filters). Same-origin limitation should be disabled for local filters.

What constants should we declare

  • adguard -- Declared always. Lets maintainers know that this is one of AdGuard products. Should be enough in 95% of cases.

Product-specific constants for some rare cases (or not so rare, thx Safari):

  • adguard_app_windows -- AG for Windows
  • adguard_app_mac -- AG for Mac
  • adguard_app_android -- AG for Android
  • adguard_app_ios -- AG for iOS
  • adguard_ext_chromium -- AG browser extension for Chrome
  • adguard_ext_firefox -- AG browser extension for Firefox
  • adguard_ext_edge -- AG browser extension for Edge
  • adguard_ext_safari -- AG browser extension for Safari
  • adguard_ext_opera -- AG browser extension for Opera
  • adguard_ext_android_cb -- AG content blocker for Samsung/Yandex

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions