[mv3] Mitigate issues when hitting regex-based rules limit

When there are too many regex-based rules, uBOL will start to drop
some strict-block rules to comply with the framework limit regarding
the maximum number of regex-based rules.

Related issues:
- https://github.com/uBlockOrigin/uBOL-home/issues/317
- https://github.com/w3c/webextensions/issues/744
This commit is contained in:
Raymond Hill 2025-04-16 08:19:52 -04:00
parent e20e6addf0
commit ec19e352b1
No known key found for this signature in database
GPG key ID: 25E1490B761470C2

View file

@ -43,6 +43,9 @@ import { ubolLog } from './debug.js';
const TRUSTED_DIRECTIVE_BASE_RULE_ID = 8000000; const TRUSTED_DIRECTIVE_BASE_RULE_ID = 8000000;
const STRICTBLOCK_PRIORITY = 29; const STRICTBLOCK_PRIORITY = 29;
let dynamicRegexCount = 0;
let sessionRegexCount = 0;
/******************************************************************************/ /******************************************************************************/
const isStrictBlockRule = rule => { const isStrictBlockRule = rule => {
@ -280,16 +283,15 @@ async function updateDynamicRules() {
]); ]);
if ( addRules.length === 0 && removeRuleIds.length === 0 ) { return; } if ( addRules.length === 0 && removeRuleIds.length === 0 ) { return; }
const maxRegexRuleCount = dnr.MAX_NUMBER_OF_REGEX_RULES; dynamicRegexCount = 0;
let regexRuleCount = 0;
let ruleId = 1; let ruleId = 1;
for ( const rule of addRules ) { for ( const rule of addRules ) {
if ( rule?.condition.regexFilter ) { regexRuleCount += 1; } if ( rule?.condition.regexFilter ) { dynamicRegexCount += 1; }
if ( (rule.id || 0) >= TRUSTED_DIRECTIVE_BASE_RULE_ID ) { continue; } if ( (rule.id || 0) >= TRUSTED_DIRECTIVE_BASE_RULE_ID ) { continue; }
rule.id = ruleId++; rule.id = ruleId++;
} }
if ( regexRuleCount !== 0 ) { if ( dynamicRegexCount !== 0 ) {
ubolLog(`Using ${regexRuleCount}/${maxRegexRuleCount} dynamic regex-based DNR rules`); ubolLog(`Using ${dynamicRegexCount}/${dnr.MAX_NUMBER_OF_REGEX_RULES} dynamic regex-based DNR rules`);
} }
return Promise.all([ return Promise.all([
dnr.updateDynamicRules({ addRules, removeRuleIds }).then(( ) => { dnr.updateDynamicRules({ addRules, removeRuleIds }).then(( ) => {
@ -402,20 +404,26 @@ async function setStrictBlockMode(state) {
/******************************************************************************/ /******************************************************************************/
async function updateSessionRules() { async function updateSessionRules() {
const addRules = []; const addRulesUnfiltered = [];
const removeRuleIds = []; const removeRuleIds = [];
const currentRules = await dnr.getSessionRules(); const currentRules = await dnr.getSessionRules();
await updateStrictBlockRules(currentRules, addRules, removeRuleIds); await updateStrictBlockRules(currentRules, addRulesUnfiltered, removeRuleIds);
if ( addRules.length === 0 && removeRuleIds.length === 0 ) { return; } if ( addRulesUnfiltered.length === 0 && removeRuleIds.length === 0 ) { return; }
const maxRegexRuleCount = dnr.MAX_NUMBER_OF_REGEX_RULES; const maxRegexCount = dnr.MAX_NUMBER_OF_REGEX_RULES * 0.95;
let regexRuleCount = 0; let regexCount = dynamicRegexCount;
let ruleId = 1; let ruleId = 1;
for ( const rule of addRules ) { for ( const rule of addRulesUnfiltered ) {
if ( rule?.condition.regexFilter ) { regexRuleCount += 1; } if ( rule?.condition.regexFilter ) { regexCount += 1; }
rule.id = ruleId++; rule.id = regexCount < maxRegexCount ? ruleId++ : 0;
} }
if ( regexRuleCount !== 0 ) { sessionRegexCount = regexCount - dynamicRegexCount;
ubolLog(`Using ${regexRuleCount}/${maxRegexRuleCount} session regex-based DNR rules`); const addRules = addRulesUnfiltered.filter(a => a.id !== 0);
const rejectedRuleCount = addRulesUnfiltered.length - addRules.length;
if ( rejectedRuleCount !== 0 ) {
ubolLog(`Too many regex-based filters, ${rejectedRuleCount} session rules dropped`);
}
if ( sessionRegexCount !== 0 ) {
ubolLog(`Using ${sessionRegexCount}/${dnr.MAX_NUMBER_OF_REGEX_RULES} session regex-based DNR rules`);
} }
return dnr.updateSessionRules({ addRules, removeRuleIds }).then(( ) => { return dnr.updateSessionRules({ addRules, removeRuleIds }).then(( ) => {
if ( removeRuleIds.length !== 0 ) { if ( removeRuleIds.length !== 0 ) {