Skip to content

Commit

Permalink
feat: handle redirect rules (#15)
Browse files Browse the repository at this point in the history
Co-authored-by: HoJeong Go <seia@outlook.kr>
  • Loading branch information
chrmod and seia-soto authored Apr 2, 2024
1 parent 5c63ca6 commit d1a430f
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 47 deletions.
Binary file modified bun.lockb
Binary file not shown.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
"test.e2e": "playwright test test/e2e/index.spec.js"
},
"dependencies": {
"@adguard/tsurlfilter": "^2.1.11",
"@eyeo/webext-ad-filtering-solution": "^1.2.0"
"@adguard/tsurlfilter": "2.2.15",
"@eyeo/webext-ad-filtering-solution": "1.5.0"
},
"devDependencies": {
"@ghostery/trackerdb": "^1.0.36",
Expand Down
6 changes: 3 additions & 3 deletions scripts/helpers/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import path from "node:path";

import { SOURCE_PATH, DIST_PATH } from "./paths.js";

export default async function build() {
export default async function build({ debug = false } = {}) {
fs.rmSync(DIST_PATH, { recursive: true, force: true });
fs.mkdirSync(DIST_PATH);
fs.copyFileSync(
Expand All @@ -15,8 +15,8 @@ export default async function build() {
entrypoints: [path.join(SOURCE_PATH, "index.js")],
outdir: DIST_PATH,
target: "browser",
minify: true,
sourcemap: "external",
minify: !debug,
sourcemap: debug ? "inline" : "external",
});

if (!result.success) {
Expand Down
2 changes: 1 addition & 1 deletion scripts/serve.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const watcher = watch(
async (event, filename) => {
console.log(`Detected ${event} in ${filename}`);
try {
await build();
await build({ debug: true });
} catch (e) {
// no need to do anything as build logs errors already
}
Expand Down
11 changes: 9 additions & 2 deletions src/converters/abp.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { FilterParsingError, normalize } from "@eyeo/webext-ad-filtering-solution/adblockpluscore/lib/filters/index.js";
import { createConverter } from "@eyeo/webext-ad-filtering-solution/adblockpluscore/lib/dnr/index.js";
import { normalizeFilter, normalizeRule } from "./helpers";
import { normalizeFilter, normalizeRule, DEFAULT_PARAM_MAPPING } from "./helpers";

const PARAM_MAPPING = {
...DEFAULT_PARAM_MAPPING,
'redirect': 'rewrite',
'redirect-rule': 'rewrite',
};

export default async function convert(filters) {
const converter = createConverter({ isRegexSupported: () => true });
Expand All @@ -9,7 +15,8 @@ export default async function convert(filters) {
let nextId = 1;
for (const filter of filters) {
try {
const normalizedFilter = normalizeFilter(normalize(filter));
const normalizedFilter = normalizeFilter(normalize(filter), { mapping: PARAM_MAPPING });

const dnrRules = converter(normalizedFilter);
if (dnrRules instanceof FilterParsingError) {
throw dnrRules;
Expand Down
42 changes: 18 additions & 24 deletions src/converters/adguard.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,26 @@
import * as AdGuardConverter from "@adguard/tsurlfilter/es/declarative-converter";
import { DeclarativeFilterConverter, Filter } from "@adguard/tsurlfilter/es/declarative-converter";
import { normalizeFilter, normalizeRule } from "./helpers.js";

const converter = new AdGuardConverter.DeclarativeFilterConverter();
const converter = new DeclarativeFilterConverter();

class Filter {
constructor(rules) {
this.content = rules.map((r => normalizeFilter(r)));
}
const createFilter = (
rules,
filterId = 0,
) => {
return new Filter(
filterId,
{ getContent: async () => rules },
);
};

getId() {
return 1;
}
export default async function convert(rules, { resourcesPath } = {}) {
const filter = createFilter(rules.map(normalizeFilter));
const conversionResult = await converter.convertStaticRuleSet(filter, { resourcesPath });
const declarativeRules = await conversionResult.ruleSet.getDeclarativeRules();

async getContent() {
return this.content;
}

async getRuleByIndex(index) {
return this.content[index];
}
}

export default async function convert(rules) {
const filter = new Filter(rules);
const result = await converter.convert([filter]);
const conversion = await result.ruleSets[0].serialize();
return {
rules: conversion.declarativeRules.map(normalizeRule),
errors: result.errors,
rules: declarativeRules.map(normalizeRule),
errors: conversionResult.errors,
limitations: conversionResult.limitations,
};
}
12 changes: 9 additions & 3 deletions src/converters/helpers.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
export function normalizeFilter(filter) {
export const DEFAULT_PARAM_MAPPING = {
'3p': 'third-party',
};

export function normalizeFilter(filter, { mapping = DEFAULT_PARAM_MAPPING } = {}) {
let [front, ...back] = filter.split("$");
let params = back.join(',').split(',');

params.forEach((param, index) => {
if (param === '3p') {
params[index] = 'third-party';
const [key, value] = param.split('=');
const alias = mapping[key];
if (alias) {
params[index] = value ? `${alias}=${value}` : alias;
}
});
// remove duplicates
Expand Down
24 changes: 17 additions & 7 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@ const $outputAbp = document.querySelector("#output-abp");
const $errorsAdguard = document.querySelector("#errors-adguard");
const $errorsAbp = document.querySelector("#errors-abp");

const ADGUARD_CONVERTER_OPTIONS = {
resourcesPath: "/web_accessible_resources",
};

$submitButton.addEventListener("click", async (ev) => {
ev.preventDefault();
const rules = $input.value.split("\n");
const rules = $input.value.split("\n").filter(Boolean);

const { rules: convertedRulesAdguard, errors: errorsAdguard } =
await convertWithAdguard(rules);
await convertWithAdguard(rules, ADGUARD_CONVERTER_OPTIONS);
const { rules: convertedRulesAbp, errors: errorsAbp } = await convertWithAbp(
rules
);
Expand All @@ -35,16 +39,22 @@ window.addEventListener("message", async (event) => {

try {
if (converter === "adguard") {
({ rules, errors } = await convertWithAdguard(filters));
({ rules, errors } = await convertWithAdguard(
filters,
ADGUARD_CONVERTER_OPTIONS
));
} else if (converter == "abp") {
({ rules, errors } = await convertWithAbp(filters));
}
} catch (e) {
errors.push(e);
}

event.source.postMessage({
rules,
errors,
}, event.origin);
event.source.postMessage(
{
rules,
errors,
},
event.origin
);
});
6 changes: 4 additions & 2 deletions test/unit/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ function normalize(rule) {
}

export async function testRule(rule) {
const { rules: adguardRules } = await convertWithAdguard([rule]);
const { rules: abpRules } = await convertWithAbp([rule]);
try {
const { rules: adguardRules } = await convertWithAdguard([rule]);
const { rules: abpRules } = await convertWithAbp([rule]);

expect(adguardRules[0]).not.toBe(undefined);
expect(normalize(adguardRules[0])).toEqual(normalize(abpRules[0]));
} catch (e) {
e.message += `
Expand Down
13 changes: 10 additions & 3 deletions test/unit/trackerdb.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { test } from "bun:test";
import { readFileSync } from "node:fs";
import path from "node:path";
import loadTrackerDB from "@ghostery/trackerdb";
import { detectFilterType } from "@cliqz/adblocker";

import { ROOT_PATH } from "../../scripts/helpers/paths.js";
import { testRule } from "./helpers.js";
Expand All @@ -20,14 +21,20 @@ const engine = readFileSync(
const trackerDB = await loadTrackerDB(engine);

const UNSUPPORTED_FILTERS = [
'/baynote(-observer)?([0-9]+)\\.js/',
'/facebook\\.com\\/(v2\\.0\\/)?(plugins|widgets)\\/.*\\.php/'
"/baynote(-observer)?([0-9]+)\\.js/",
"/facebook\\.com\\/(v2\\.0\\/)?(plugins|widgets)\\/.*\\.php/",
];

test("TrackerDB filters", async () => {
for (const pattern of trackerDB.engine.metadata.getPatterns()) {
for (const filter of pattern.filters) {
if (UNSUPPORTED_FILTERS.includes(filter)) {
if (
UNSUPPORTED_FILTERS.includes(filter) ||
// not supported - https://gitlab.com/eyeo/adblockplus/abc/webext-ad-filtering-solution/-/issues/572
filter.includes(".*") ||
// ignore cosmetic filters
detectFilterType(filter) === 2
) {
continue;
}
await testRule(filter);
Expand Down

0 comments on commit d1a430f

Please sign in to comment.