mirror of
https://github.com/gorhill/uBlock.git
synced 2026-03-11 09:04:36 +00:00
[mv3] Eliminate false positives in new generic cosmetic exception code
Related commit:
a009623d97
This commit is contained in:
parent
4032ba01bf
commit
68962453ff
3 changed files with 84 additions and 38 deletions
|
|
@ -29,6 +29,9 @@ const genericSelectorMap = self.genericSelectorMap || new Map();
|
|||
self.genericSelectorMap = undefined;
|
||||
if ( genericSelectorMap.size === 0 ) { return; }
|
||||
|
||||
const genericExceptionSieve = self.genericExceptionSieve || new Set();
|
||||
self.genericExceptionSieve = undefined;
|
||||
|
||||
const genericExceptionMap = self.genericExceptionMap || new Map();
|
||||
self.genericExceptionMap = undefined;
|
||||
|
||||
|
|
@ -78,8 +81,11 @@ const uBOL_idFromNode = (node, out) => {
|
|||
const selectorList = genericSelectorMap.get(hash);
|
||||
if ( selectorList === undefined ) { return; }
|
||||
genericSelectorMap.delete(hash);
|
||||
if ( isExcepted(hash) ) { return; }
|
||||
out.push(selectorList);
|
||||
if ( genericExceptionSieve.has(hash) ) {
|
||||
applyExceptions(selectorList, out);
|
||||
} else {
|
||||
out.push(selectorList);
|
||||
}
|
||||
};
|
||||
|
||||
// https://github.com/uBlockOrigin/uBlock-issues/discussions/2076
|
||||
|
|
@ -99,18 +105,26 @@ const uBOL_classesFromNode = (node, out) => {
|
|||
const selectorList = genericSelectorMap.get(hash);
|
||||
if ( selectorList === undefined ) { continue; }
|
||||
genericSelectorMap.delete(hash);
|
||||
if ( isExcepted(hash) ) { continue; }
|
||||
out.push(selectorList);
|
||||
if ( genericExceptionSieve.has(hash) ) {
|
||||
applyExceptions(selectorList, out);
|
||||
} else {
|
||||
out.push(selectorList);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const isExcepted = hash => {
|
||||
const hostnames = genericExceptionMap.get(hash);
|
||||
if ( hostnames === undefined ) { return; }
|
||||
const hasEntities = hostnames.includes('.*');
|
||||
return self.isolatedAPI.forEachHostname((hostname) => {
|
||||
if ( hostnames.includes(` ${hostname} `) ) { return true; }
|
||||
}, { hasEntities });
|
||||
const applyExceptions = (selectorList, out) => {
|
||||
const selectors = new Set(selectorList.split(',\n'));
|
||||
self.isolatedAPI.forEachHostname(hostname => {
|
||||
const exceptions = genericExceptionMap.get(hostname);
|
||||
if ( exceptions === undefined ) { return; }
|
||||
for ( const exception of exceptions.split('\n') ) {
|
||||
selectors.delete(exception);
|
||||
}
|
||||
if ( selectors.size === 0 ) { return true; }
|
||||
}, { hasEntities: true });
|
||||
if ( selectors.size === 0 ) { return; }
|
||||
out.push(Array.from(selectors).join(',\n'));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
|||
|
|
@ -700,25 +700,31 @@ async function processGenericCosmeticFilters(
|
|||
if ( selectors === undefined ) {
|
||||
genericSelectorMap.set(hash, selector)
|
||||
} else {
|
||||
genericSelectorMap.set(hash, `${selectors},${selector}`)
|
||||
genericSelectorMap.set(hash, `${selectors},\n${selector}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Specific exceptions
|
||||
const genericExceptionSieve = new Set();
|
||||
const genericExceptionMap = new Map();
|
||||
if ( declarativeMap ) {
|
||||
for ( const details of declarativeMap.values() ) {
|
||||
for ( const [ exception, details ] of declarativeMap ) {
|
||||
if ( details.rejected ) { continue; }
|
||||
if ( details.key === undefined ) { continue; }
|
||||
if ( details.matches !== undefined ) { continue; }
|
||||
if ( details.excludeMatches === undefined ) { continue; }
|
||||
const type = details.key.charCodeAt(0);
|
||||
const hash = hashFromStr(type, details.key.slice(1));
|
||||
const hostnames = genericExceptionMap.get(hash) ?? '';
|
||||
genericExceptionMap.set(hash,
|
||||
`${hostnames} ${details.excludeMatches.join(' ')} `
|
||||
);
|
||||
genericExceptionSieve.add(hash);
|
||||
for ( const hn of details.excludeMatches ) {
|
||||
const exceptions = genericExceptionMap.get(hn);
|
||||
if ( exceptions === undefined ) {
|
||||
genericExceptionMap.set(hn, exception);
|
||||
} else {
|
||||
genericExceptionMap.set(hn, `${exceptions}\n${exception}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -735,6 +741,10 @@ async function processGenericCosmeticFilters(
|
|||
/\bself\.\$genericSelectorMap\$/,
|
||||
`${JSON.stringify(genericSelectorMap, scriptletJsonReplacer)}`
|
||||
);
|
||||
patchedScriptlet = safeReplace(patchedScriptlet,
|
||||
/\bself\.\$genericExceptionSieve\$/,
|
||||
`${JSON.stringify(genericExceptionSieve, scriptletJsonReplacer)}`
|
||||
);
|
||||
patchedScriptlet = safeReplace(patchedScriptlet,
|
||||
/\bself\.\$genericExceptionMap\$/,
|
||||
`${JSON.stringify(genericExceptionMap, scriptletJsonReplacer)}`
|
||||
|
|
@ -745,10 +755,10 @@ async function processGenericCosmeticFilters(
|
|||
patchedScriptlet
|
||||
);
|
||||
|
||||
log(`CSS-generic: ${genericExceptionSieve.size} specific CSS exceptions`);
|
||||
log(`CSS-generic: ${genericSelectorMap.size} plain CSS selectors`);
|
||||
log(`CSS-generic: ${genericExceptionMap.size} specific CSS exceptions`);
|
||||
|
||||
return genericSelectorMap.size + genericExceptionMap.size;
|
||||
return genericSelectorMap.size + genericExceptionSieve.size;
|
||||
}
|
||||
|
||||
const hashFromStr = (type, s) => {
|
||||
|
|
@ -1491,6 +1501,9 @@ async function main() {
|
|||
urls: [ 'https://ublockorigin.github.io/uBOL-home/tests/test-filters.txt' ],
|
||||
homeURL: 'https://ublockorigin.github.io/uBOL-home/tests/test-filters.html',
|
||||
filters: [
|
||||
'###gcf #gcf1 .fail',
|
||||
'###gcf #gcf2 .fail',
|
||||
'ublockorigin.github.io,localhost#@##gcf #gcf2 .fail',
|
||||
],
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -27,38 +27,57 @@
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
const selectorsToImport = self.$genericSelectorMap$;
|
||||
const exceptionsToImport = self.$genericExceptionMap$;
|
||||
const genericSelectorMap = self.$genericSelectorMap$;
|
||||
const genericExceptionSieve = self.$genericExceptionSieve$;
|
||||
const genericExceptionMap = self.$genericExceptionMap$;
|
||||
|
||||
if ( selectorsToImport ) {
|
||||
if ( genericSelectorMap ) {
|
||||
const map = self.genericSelectorMap =
|
||||
self.genericSelectorMap || new Map();
|
||||
|
||||
if ( map.size !== 0 ) {
|
||||
for ( const entry of selectorsToImport ) {
|
||||
for ( const entry of genericSelectorMap ) {
|
||||
const before = map.get(entry[0]);
|
||||
map.set(entry[0],
|
||||
before === undefined ? entry[1] : `${before},${entry[1]}`
|
||||
);
|
||||
if ( before === undefined ) {
|
||||
map.set(entry[0], entry[1]);
|
||||
} else {
|
||||
map.set(entry[0], `${before},\n${entry[1]}`);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.genericSelectorMap = new Map(selectorsToImport);
|
||||
self.genericSelectorMap = new Map(genericSelectorMap);
|
||||
}
|
||||
selectorsToImport.length = 0;
|
||||
genericSelectorMap.length = 0;
|
||||
}
|
||||
|
||||
if ( exceptionsToImport ) {
|
||||
const map = self.genericExceptionMap =
|
||||
self.genericExceptionMap || new Map();
|
||||
|
||||
if ( map.size !== 0 ) {
|
||||
for ( const entry of exceptionsToImport ) {
|
||||
map.set(entry[0], `${map.get(entry[0]) || ''}${entry[1]}`);
|
||||
if ( genericExceptionSieve ) {
|
||||
const hashes = self.genericExceptionSieve =
|
||||
self.genericExceptionSieve || new Set();
|
||||
if ( hashes.size !== 0 ) {
|
||||
for ( const hash of genericExceptionSieve ) {
|
||||
hashes.add(hash);
|
||||
}
|
||||
} else {
|
||||
self.genericExceptionMap = new Map(exceptionsToImport);
|
||||
self.genericExceptionSieve = new Set(genericExceptionSieve);
|
||||
}
|
||||
exceptionsToImport.length = 0;
|
||||
genericExceptionSieve.length = 0;
|
||||
}
|
||||
|
||||
if ( genericExceptionMap ) {
|
||||
const map = self.genericExceptionMap =
|
||||
self.genericExceptionMap || new Map();
|
||||
if ( map.size !== 0 ) {
|
||||
for ( const entry of genericExceptionMap ) {
|
||||
const before = map.get(entry[0]);
|
||||
if ( before === undefined ) {
|
||||
map.set(entry[0], entry[1]);
|
||||
} else {
|
||||
map.set(entry[0], `${before}\n${entry[1]}`);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.genericExceptionMap = new Map(genericExceptionMap);
|
||||
}
|
||||
genericExceptionMap.length = 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
|||
Loading…
Reference in a new issue