Skip to content

Commit

Permalink
Adblocker: fix $replace and service worker blocking (#2066)
Browse files Browse the repository at this point in the history
  • Loading branch information
chrmod authored Nov 18, 2024
1 parent 0b92cfc commit bae45d5
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 28 deletions.
46 changes: 21 additions & 25 deletions src/background/adblocker.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ function getEnabledEngines(config) {
list.push(engines.FIXES_ENGINE);
}

if (config.customFilters.enabled) {
list.push(engines.CUSTOM_ENGINE);
}
// Custom filters should be always added as
// they have own settings which defines if they are enabled
list.push(engines.CUSTOM_ENGINE);

return list;
}
Expand All @@ -58,7 +58,7 @@ function pause(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}

async function reloadMainEngine() {
export async function reloadMainEngine() {
// Delay the reload to avoid UI freezes in Firefox and Safari
if (__PLATFORM__ !== 'chromium') await pause(1000);

Expand All @@ -83,13 +83,11 @@ async function reloadMainEngine() {
`[adblocker] Main engine reloaded with: ${enabledEngines.join(', ')}`,
);
} else {
engines.create(engines.MAIN_ENGINE);
await engines.create(engines.MAIN_ENGINE);
console.info('[adblocker] Main engine reloaded with no filters');
}
}

engines.addChangeListener(engines.CUSTOM_ENGINE, reloadMainEngine);

let updating = false;
async function updateEngines() {
if (updating) return;
Expand Down Expand Up @@ -367,9 +365,16 @@ function isTrusted(request, type) {
}

if (__PLATFORM__ === 'firefox') {
function isExtensionRequest(details) {
return (
(details.tabId === -1 && details.url.startsWith('moz-extension://')) ||
details.originUrl?.startsWith('moz-extension://')
);
}

chrome.webRequest.onBeforeRequest.addListener(
(details) => {
if (details.tabId < 0 || details.type === 'main_frame') return;
if (details.type === 'main_frame' || isExtensionRequest(details)) return;

if (setup.pending) {
console.error('[adblocker] not ready for network requests blocking');
Expand Down Expand Up @@ -403,30 +408,20 @@ if (__PLATFORM__ === 'firefox') {

chrome.webRequest.onHeadersReceived.addListener(
(details) => {
if (details.tabId < 0 || details.type === 'main_frame') return;
if (isExtensionRequest(details)) return;

if (setup.pending) {
console.error('[adblocker] not ready for network headers modification');
return;
}

const request = Request.fromRequestDetails(details);
const cspPolicies = [];
const htmlFilters = [];

if (!isTrusted(request, details.type)) {
const engine = engines.get(engines.MAIN_ENGINE);
if (isTrusted(request, details.type)) return;

htmlFilters.push(...engine.getHtmlFilters(request));

if (details.type === 'main_frame') {
const policies = engine.getCSPDirectives(request);
if (policies !== undefined) {
cspPolicies.push(...policies);
}
}
}
const engine = engines.get(engines.MAIN_ENGINE);

const htmlFilters = engine.getHtmlFilters(request);
if (htmlFilters.length !== 0) {
request.modified = true;
updateTabStats(details.tabId, [request]);
Expand All @@ -437,9 +432,10 @@ if (__PLATFORM__ === 'firefox') {
);
}

if (cspPolicies.length !== 0) {
return updateResponseHeadersWithCSP(details, cspPolicies);
}
if (details.type !== 'main_frame') return;
const cspPolicies = engine.getCSPDirectives(request);
if (!cspPolicies || cspPolicies.length === 0) return;
return updateResponseHeadersWithCSP(details, cspPolicies);
},
{ urls: ['http://*/*', 'https://*/*'] },
['blocking', 'responseHeaders'],
Expand Down
10 changes: 7 additions & 3 deletions src/background/custom-filters.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import * as OptionsObserver from '/utils/options-observer.js';
import Options from '/store/options.js';
import CustomFilters from '/store/custom-filters.js';

import { setup } from '/background/adblocker.js';
import { setup, reloadMainEngine } from '/background/adblocker.js';

const convert =
__PLATFORM__ === 'chromium'
Expand Down Expand Up @@ -176,6 +176,10 @@ async function update(text, { trustedScriptlets }) {

result.errors = errors;

// Update main engine with custom filters
await reloadMainEngine();

// Update DNR rules for Chromium and Safari
if (__PLATFORM__ === 'chromium' || __PLATFORM__ === 'safari') {
const dnrResult = await Promise.allSettled(
[...networkFilters].map((filter) => convert(filter)),
Expand Down Expand Up @@ -221,7 +225,7 @@ OptionsObserver.addListener('customFilters', async (value, lastValue) => {

// If we cannot initialize engine, we need to update it
if (!(await engines.init(engines.CUSTOM_ENGINE))) {
update((await store.resolve(CustomFilters)).text, {
await update((await store.resolve(CustomFilters)).text, {
trustedScriptlets,
});
}
Expand All @@ -232,7 +236,7 @@ OptionsObserver.addListener('customFilters', async (value, lastValue) => {
return;
}

update(enabled ? (await store.resolve(CustomFilters)).text : '', {
await update(enabled ? (await store.resolve(CustomFilters)).text : '', {
trustedScriptlets,
});
}
Expand Down
12 changes: 12 additions & 0 deletions tests/e2e/spec/advanced.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,18 @@ describe('Advanced Features', function () {
});
});

// Scope for Firefox webRequest API tests
if (browser.isFirefox) {
it('adds $replace network filter', async function () {
await setCustomFilters([
`||${PAGE_DOMAIN}^$replace=/<title>.*<\\/title>/<title>hello world<\\/title>/`,
]);

await browser.url(PAGE_URL, { wait: 'networkIdle' });
await expect(await browser.getTitle()).toBe('hello world');
});
}

it('removes custom filters in settings page', async function () {
await setCustomFilters([]);
await setPrivacyToggle('custom-filters', false);
Expand Down

0 comments on commit bae45d5

Please sign in to comment.