Skip to content

Commit a9a78d4

Browse files
committed
[mv3] Various approach to minimize DNR ruleset file
Related issue: https://github.com/mozilla/addons-server/issues/4717
1 parent 9d69699 commit a9a78d4

File tree

1 file changed

+82
-1
lines changed

1 file changed

+82
-1
lines changed

platform/mv3/make-rulesets.js

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,54 @@ const isGood = rule =>
249249

250250
/******************************************************************************/
251251

252+
// Two distinct hostnames:
253+
// www.example.com
254+
// example.com
255+
// Can be reduced to a single one:
256+
// example.com
257+
// Since if example.com matches, then www.example.com (or any other subdomain
258+
// of example.com) will always match.
259+
260+
function pruneHostnameArray(hostnames) {
261+
const rootMap = new Map();
262+
for ( const hostname of hostnames ) {
263+
const labels = hostname.split('.');
264+
let currentMap = rootMap;
265+
let i = labels.length;
266+
while ( i-- ) {
267+
const label = labels[i];
268+
let nextMap = currentMap.get(label);
269+
if ( nextMap === null ) { break; }
270+
if ( nextMap === undefined ) {
271+
if ( i === 0 ) {
272+
currentMap.set(label, (nextMap = null));
273+
} else {
274+
currentMap.set(label, (nextMap = new Map()));
275+
}
276+
} else if ( i === 0 ) {
277+
currentMap.set(label, null);
278+
}
279+
currentMap = nextMap;
280+
}
281+
}
282+
const assemble = (currentMap, currentHostname, out) => {
283+
for ( const [ label, nextMap ] of currentMap ) {
284+
const nextHostname = currentHostname === ''
285+
? label
286+
: `${label}.${currentHostname}`;
287+
if ( nextMap === null ) {
288+
out.push(nextHostname);
289+
} else {
290+
assemble(nextMap, nextHostname, out);
291+
}
292+
}
293+
return out;
294+
};
295+
return assemble(rootMap, '', []);
296+
}
297+
298+
/******************************************************************************/
299+
252300
async function processNetworkFilters(assetDetails, network) {
253301
const replacer = (k, v) => {
254302
if ( k.startsWith('_') ) { return; }
@@ -271,6 +319,37 @@ async function processNetworkFilters(assetDetails, network) {
271319
log(`\tRejected filter count: ${network.rejectedFilterCount}`);
272320
log(`Output rule count: ${rules.length}`);
273321

322+
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest/RuleCondition#browser_compatibility
323+
// isUrlFilterCaseSensitive is false by default in Firefox. It will be
324+
// false by default in Chromium 118+.
325+
if ( platform === 'firefox' ) {
326+
for ( const rule of rules ) {
327+
if ( rule.condition === undefined ) { continue; }
328+
if ( rule.condition.urlFilter === undefined ) {
329+
if ( rule.condition.regexFilter === undefined ) { continue; }
330+
}
331+
if ( rule.condition.isUrlFilterCaseSensitive === undefined ) {
332+
rule.condition.isUrlFilterCaseSensitive = true;
333+
} else if ( rule.condition.isUrlFilterCaseSensitive === false ) {
334+
rule.condition.isUrlFilterCaseSensitive = undefined;
335+
}
336+
}
337+
}
338+
339+
// Minimize requestDomains arrays
340+
for ( const rule of rules ) {
341+
const condition = rule.condition;
342+
if ( condition === undefined ) { continue; }
343+
const requestDomains = condition.requestDomains;
344+
if ( requestDomains === undefined ) { continue; }
345+
const beforeCount = requestDomains.length;
346+
condition.requestDomains = pruneHostnameArray(requestDomains);
347+
const afterCount = condition.requestDomains.length;
348+
if ( afterCount !== beforeCount ) {
349+
log(`\tPruning requestDomains: from ${beforeCount} to ${afterCount}`);
350+
}
351+
}
352+
274353
const plainGood = rules.filter(rule => isGood(rule) && isRegex(rule) === false);
275354
log(`\tPlain good: ${plainGood.length}`);
276355
log(plainGood
@@ -314,9 +393,11 @@ async function processNetworkFilters(assetDetails, network) {
314393
log(`\tUnsupported: ${bad.length}`);
315394
log(bad.map(rule => rule._error.map(v => `\t\t${v}`)).join('\n'), true);
316395

396+
const jsonIndent = platform !== 'firefox' ? 1 : undefined;
397+
317398
writeFile(
318399
`${rulesetDir}/main/${assetDetails.id}.json`,
319-
`${JSON.stringify(plainGood, replacer, 1)}\n`
400+
`${JSON.stringify(plainGood, replacer, jsonIndent)}\n`
320401
);
321402

322403
if ( regexes.length !== 0 ) {

0 commit comments

Comments
 (0)