mirror of
https://github.com/gorhill/uBlock.git
synced 2026-03-11 09:04:36 +00:00
[mv3] Ensure no generic cosmetic filters end up in specific realm
Related issue: https://github.com/uBlockOrigin/uBOL-home/issues/254 Cosmetic filters with only negated hostnames would end up being classified as specific, while in reality the filter is generic, with specific exceptions. This commit fixes the improper classification. Enforcing specific exception filters in the generic realm is still an issue to address.
This commit is contained in:
parent
ec5a1b3ab6
commit
56ba93700c
2 changed files with 55 additions and 55 deletions
|
|
@ -83,11 +83,6 @@ const uidint32 = (s) => {
|
|||
return parseInt(h,16) & 0x7FFFFFFF;
|
||||
};
|
||||
|
||||
const hnSort = (a, b) =>
|
||||
a.split('.').reverse().join('.').localeCompare(
|
||||
b.split('.').reverse().join('.')
|
||||
);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
const stdOutput = [];
|
||||
|
|
@ -681,14 +676,10 @@ function groupHostnamesBySelectors(arrayin) {
|
|||
const out = Array.from(contentMap).map(a => [
|
||||
a[0], {
|
||||
a: a[1].a,
|
||||
y: a[1].y ? Array.from(a[1].y).sort(hnSort) : '*',
|
||||
y: a[1].y ? Array.from(a[1].y) : undefined,
|
||||
n: a[1].n ? Array.from(a[1].n) : undefined,
|
||||
}
|
||||
]).sort((a, b) => {
|
||||
const ha = Array.isArray(a[1].y) ? a[1].y[0] : '*';
|
||||
const hb = Array.isArray(b[1].y) ? b[1].y[0] : '*';
|
||||
return hnSort(ha, hb);
|
||||
});
|
||||
]);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -90,6 +90,39 @@ const keyFromSelector = selector => {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
function addGenericCosmeticFilter(context, selector, isException) {
|
||||
if ( selector === undefined ) { return; }
|
||||
if ( selector.length <= 1 ) { return; }
|
||||
if ( isException ) {
|
||||
if ( context.genericCosmeticExceptions === undefined ) {
|
||||
context.genericCosmeticExceptions = new Set();
|
||||
}
|
||||
context.genericCosmeticExceptions.add(selector);
|
||||
return;
|
||||
}
|
||||
if ( selector.charCodeAt(0) === 0x7B /* '{' */ ) { return; }
|
||||
const key = keyFromSelector(selector);
|
||||
if ( key === undefined ) {
|
||||
if ( context.genericHighCosmeticFilters === undefined ) {
|
||||
context.genericHighCosmeticFilters = new Set();
|
||||
}
|
||||
context.genericHighCosmeticFilters.add(selector);
|
||||
return;
|
||||
}
|
||||
const type = key.charCodeAt(0);
|
||||
const hash = hashFromStr(type, key.slice(1));
|
||||
if ( context.genericCosmeticFilters === undefined ) {
|
||||
context.genericCosmeticFilters = new Map();
|
||||
}
|
||||
let bucket = context.genericCosmeticFilters.get(hash);
|
||||
if ( bucket === undefined ) {
|
||||
context.genericCosmeticFilters.set(hash, bucket = []);
|
||||
}
|
||||
bucket.push(selector);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
function addExtendedToDNR(context, parser) {
|
||||
if ( parser.isExtendedFilter() === false ) { return false; }
|
||||
|
||||
|
|
@ -195,35 +228,8 @@ function addExtendedToDNR(context, parser) {
|
|||
|
||||
// Generic cosmetic filtering
|
||||
if ( parser.hasOptions() === false ) {
|
||||
const { compiled } = parser.result;
|
||||
if ( compiled === undefined ) { return; }
|
||||
if ( compiled.length <= 1 ) { return; }
|
||||
if ( parser.isException() ) {
|
||||
if ( context.genericCosmeticExceptions === undefined ) {
|
||||
context.genericCosmeticExceptions = new Set();
|
||||
}
|
||||
context.genericCosmeticExceptions.add(compiled);
|
||||
return;
|
||||
}
|
||||
if ( compiled.charCodeAt(0) === 0x7B /* '{' */ ) { return; }
|
||||
const key = keyFromSelector(compiled);
|
||||
if ( key === undefined ) {
|
||||
if ( context.genericHighCosmeticFilters === undefined ) {
|
||||
context.genericHighCosmeticFilters = new Set();
|
||||
}
|
||||
context.genericHighCosmeticFilters.add(compiled);
|
||||
return;
|
||||
}
|
||||
const type = key.charCodeAt(0);
|
||||
const hash = hashFromStr(type, key.slice(1));
|
||||
if ( context.genericCosmeticFilters === undefined ) {
|
||||
context.genericCosmeticFilters = new Map();
|
||||
}
|
||||
let bucket = context.genericCosmeticFilters.get(hash);
|
||||
if ( bucket === undefined ) {
|
||||
context.genericCosmeticFilters.set(hash, bucket = []);
|
||||
}
|
||||
bucket.push(compiled);
|
||||
const { compiled, exception } = parser.result;
|
||||
addGenericCosmeticFilter(context, compiled, exception);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -234,26 +240,22 @@ function addExtendedToDNR(context, parser) {
|
|||
if ( context.specificCosmeticFilters === undefined ) {
|
||||
context.specificCosmeticFilters = new Map();
|
||||
}
|
||||
const { compiled, exception, raw } = parser.result;
|
||||
if ( compiled === undefined ) {
|
||||
context.specificCosmeticFilters.set(`Invalid filter: ...##${raw}`, {
|
||||
rejected: true
|
||||
});
|
||||
return;
|
||||
}
|
||||
let details = context.specificCosmeticFilters.get(compiled);
|
||||
for ( const { hn, not, bad } of parser.getExtFilterDomainIterator() ) {
|
||||
if ( bad ) { continue; }
|
||||
if ( not && exception ) { continue; }
|
||||
if ( isRegex(hn) ) { continue; }
|
||||
let { compiled, exception, raw } = parser.result;
|
||||
if ( exception ) { continue; }
|
||||
let rejected;
|
||||
if ( compiled === undefined ) {
|
||||
rejected = `Invalid filter: ${hn}##${raw}`;
|
||||
}
|
||||
if ( rejected ) {
|
||||
compiled = rejected;
|
||||
}
|
||||
let details = context.specificCosmeticFilters.get(compiled);
|
||||
if ( details === undefined ) {
|
||||
details = {};
|
||||
if ( rejected ) { details.rejected = true; }
|
||||
context.specificCosmeticFilters.set(compiled, details);
|
||||
context.specificCosmeticFilters.set(compiled, details = {});
|
||||
}
|
||||
if ( rejected ) { continue; }
|
||||
if ( not ) {
|
||||
if ( exception ) {
|
||||
if ( details.excludeMatches === undefined ) {
|
||||
details.excludeMatches = [];
|
||||
}
|
||||
|
|
@ -270,6 +272,13 @@ function addExtendedToDNR(context, parser) {
|
|||
}
|
||||
details.matches.push(hn);
|
||||
}
|
||||
if ( details === undefined ) { return; }
|
||||
if ( exception ) { return; }
|
||||
if ( compiled.startsWith('{') ) { return; }
|
||||
if ( details.matches === undefined || details.matches.includes('*') ) {
|
||||
addGenericCosmeticFilter(context, compiled, false);
|
||||
details.matches = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
|||
Loading…
Reference in a new issue