Skip to content

Commit

Permalink
Prune rules with invalid regex-based filter for all realms
Browse files Browse the repository at this point in the history
  • Loading branch information
gorhill committed Oct 3, 2023
1 parent 1268f77 commit 7416340
Showing 1 changed file with 63 additions and 49 deletions.
112 changes: 63 additions & 49 deletions platform/mv3/extension/js/ruleset-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,25 +74,59 @@ function getDynamicRules() {

/******************************************************************************/

async function updateRegexRules() {
const [
rulesetDetails,
dynamicRules
] = await Promise.all([
getEnabledRulesetsDetails(),
dnr.getDynamicRules(),
]);

async function pruneInvalidRegexRules(realm, rulesIn) {
// Avoid testing already tested regexes
const dynamicRules = await dnr.getDynamicRules();
const validRegexSet = new Set(
dynamicRules.filter(rule =>
rule.condition?.regexFilter && true || false
).map(rule =>
rule.condition.regexFilter
)
);
const allRules = [];

// Validate regex-based rules
const toCheck = [];
const rejectedRegexRules = [];
for ( const rule of rulesIn ) {
if ( rule.condition?.regexFilter === undefined ) {
toCheck.push(true);
continue;
}
const {
regexFilter: regex,
isUrlFilterCaseSensitive: isCaseSensitive
} = rule.condition;
if ( validRegexSet.has(regex) ) {
toCheck.push(true);
continue;
}
toCheck.push(
dnr.isRegexSupported({ regex, isCaseSensitive }).then(result => {
if ( result.isSupported ) { return true; }
rejectedRegexRules.push(`\t${regex} ${result.reason}`);
return false;
})
);
}

// Collate results
const isValid = await Promise.all(toCheck);

if ( rejectedRegexRules.length !== 0 ) {
ubolLog(
`${realm} realm: rejected regexes:\n`,
rejectedRegexRules.join('\n')
);
}

return rulesIn.filter((v, i) => isValid[i]);
}

/******************************************************************************/

async function updateRegexRules() {
const rulesetDetails = await getEnabledRulesetsDetails();

// Fetch regexes for all enabled rulesets
const toFetch = [];
Expand All @@ -102,49 +136,23 @@ async function updateRegexRules() {
}
const regexRulesets = await Promise.all(toFetch);

// Validate fetched regexes
// Collate all regexes rules
const allRules = [];
let regexRuleId = REGEXES_REALM_START;
for ( const rules of regexRulesets ) {
if ( Array.isArray(rules) === false ) { continue; }
for ( const rule of rules ) {
rule.id = regexRuleId++;
const {
regexFilter: regex,
isUrlFilterCaseSensitive: isCaseSensitive
} = rule.condition;
allRules.push(rule);
toCheck.push(
validRegexSet.has(regex)
? { isSupported: true }
: dnr.isRegexSupported({ regex, isCaseSensitive })
);
}
}

// Collate results
const results = await Promise.all(toCheck);
const newRules = [];
const rejectedRegexRules = [];
for ( let i = 0; i < allRules.length; i++ ) {
const rule = allRules[i];
const result = results[i];
if ( result instanceof Object && result.isSupported ) {
newRules.push(rule);
} else {
rejectedRegexRules.push(rule);
}
}
if ( rejectedRegexRules.length !== 0 ) {
ubolLog(
'Rejected regexes:',
rejectedRegexRules.map(rule => rule.condition.regexFilter)
);
}
const validatedRules = await pruneInvalidRegexRules('regexes', allRules);

// Add validated regex rules to dynamic ruleset without affecting rules
// outside regex rules realm.
const dynamicRuleMap = await getDynamicRules();
const newRuleMap = new Map(newRules.map(rule => [ rule.id, rule ]));
const newRuleMap = new Map(validatedRules.map(rule => [ rule.id, rule ]));
const addRules = [];
const removeRuleIds = [];

Expand Down Expand Up @@ -202,21 +210,23 @@ async function updateRemoveparamRules() {
const removeparamRulesets = await Promise.all(toFetch);

// Removeparam rules can only be enforced with omnipotence
const newRules = [];
const allRules = [];
if ( hasOmnipotence ) {
let removeparamRuleId = REMOVEPARAMS_REALM_START;
for ( const rules of removeparamRulesets ) {
if ( Array.isArray(rules) === false ) { continue; }
for ( const rule of rules ) {
rule.id = removeparamRuleId++;
newRules.push(rule);
allRules.push(rule);
}
}
}

const validatedRules = await pruneInvalidRegexRules('removeparam', allRules);

// Add removeparam rules to dynamic ruleset without affecting rules
// outside removeparam rules realm.
const newRuleMap = new Map(newRules.map(rule => [ rule.id, rule ]));
const newRuleMap = new Map(validatedRules.map(rule => [ rule.id, rule ]));
const addRules = [];
const removeRuleIds = [];

Expand Down Expand Up @@ -274,21 +284,23 @@ async function updateRedirectRules() {
const redirectRulesets = await Promise.all(toFetch);

// Redirect rules can only be enforced with omnipotence
const newRules = [];
const allRules = [];
if ( hasOmnipotence ) {
let redirectRuleId = REDIRECT_REALM_START;
for ( const rules of redirectRulesets ) {
if ( Array.isArray(rules) === false ) { continue; }
for ( const rule of rules ) {
rule.id = redirectRuleId++;
newRules.push(rule);
allRules.push(rule);
}
}
}

const validatedRules = await pruneInvalidRegexRules('redirect', allRules);

// Add redirect rules to dynamic ruleset without affecting rules
// outside redirect rules realm.
const newRuleMap = new Map(newRules.map(rule => [ rule.id, rule ]));
const newRuleMap = new Map(validatedRules.map(rule => [ rule.id, rule ]));
const addRules = [];
const removeRuleIds = [];

Expand Down Expand Up @@ -346,21 +358,23 @@ async function updateModifyHeadersRules() {
const rulesets = await Promise.all(toFetch);

// Redirect rules can only be enforced with omnipotence
const newRules = [];
const allRules = [];
if ( hasOmnipotence ) {
let ruleId = MODIFYHEADERS_REALM_START;
for ( const rules of rulesets ) {
if ( Array.isArray(rules) === false ) { continue; }
for ( const rule of rules ) {
rule.id = ruleId++;
newRules.push(rule);
allRules.push(rule);
}
}
}

const validatedRules = await pruneInvalidRegexRules('modify-headers', allRules);

// Add modifyHeaders rules to dynamic ruleset without affecting rules
// outside modifyHeaders realm.
const newRuleMap = new Map(newRules.map(rule => [ rule.id, rule ]));
const newRuleMap = new Map(validatedRules.map(rule => [ rule.id, rule ]));
const addRules = [];
const removeRuleIds = [];

Expand Down

0 comments on commit 7416340

Please sign in to comment.