Compare commits

...

3 commits

Author SHA1 Message Date
Fanboynz
85f39d2e45
Merge 897ebb5a48 into 56ba93700c 2024-12-08 18:35:14 +01:00
Raymond Hill
56ba93700c
[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.
2024-12-08 08:37:29 -05:00
ryanbr
897ebb5a48 Add all/none in set-local/cookie 2024-12-06 07:57:56 +00:00
3 changed files with 56 additions and 55 deletions

View file

@ -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;
}

View file

@ -44,6 +44,7 @@ export function getSafeCookieValuesFn() {
'on', 'off',
'true', 't', 'false', 'f',
'yes', 'y', 'no', 'n',
'all', 'none',
];
}
registerScriptlet(getSafeCookieValuesFn, {

View file

@ -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;
}
}
/******************************************************************************/