mirror of
https://github.com/gorhill/uBlock.git
synced 2024-09-18 08:52:26 +02:00
new filter option: "badfilter" (see https://github.com/uBlockOrigin/uAssets/issues/192)
This commit is contained in:
parent
e8375f91cd
commit
a4e20ae3ad
@ -1148,10 +1148,11 @@ FilterContainer.prototype.fromCompiledContent = function(lineIter, skipGenericCo
|
|||||||
fieldIter = new µb.FieldIterator('\v');
|
fieldIter = new µb.FieldIterator('\v');
|
||||||
|
|
||||||
while ( lineIter.eot() === false ) {
|
while ( lineIter.eot() === false ) {
|
||||||
if ( lineIter.text.charCodeAt(lineIter.offset) !== 0x63 /* 'c' */ ) {
|
line = lineIter.next();
|
||||||
|
if ( line.charCodeAt(0) !== 0x63 /* 'c' */ ) {
|
||||||
|
lineIter.rewind();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
line = lineIter.next();
|
|
||||||
|
|
||||||
this.acceptedCount += 1;
|
this.acceptedCount += 1;
|
||||||
if ( this.duplicateBuster.has(line) ) {
|
if ( this.duplicateBuster.has(line) ) {
|
||||||
@ -1274,10 +1275,11 @@ FilterContainer.prototype.skipGenericCompiledContent = function(lineIter) {
|
|||||||
fieldIter = new µb.FieldIterator('\v');
|
fieldIter = new µb.FieldIterator('\v');
|
||||||
|
|
||||||
while ( lineIter.eot() === false ) {
|
while ( lineIter.eot() === false ) {
|
||||||
if ( lineIter.text.charCodeAt(lineIter.offset) !== 0x63 /* 'c' */ ) {
|
line = lineIter.next();
|
||||||
|
if ( line.charCodeAt(0) !== 0x63 /* 'c' */ ) {
|
||||||
|
lineIter.rewind();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
line = lineIter.next();
|
|
||||||
|
|
||||||
this.acceptedCount += 1;
|
this.acceptedCount += 1;
|
||||||
if ( this.duplicateBuster.has(line) ) {
|
if ( this.duplicateBuster.has(line) ) {
|
||||||
@ -1336,10 +1338,11 @@ FilterContainer.prototype.skipCompiledContent = function(lineIter) {
|
|||||||
fieldIter = new µb.FieldIterator('\v');
|
fieldIter = new µb.FieldIterator('\v');
|
||||||
|
|
||||||
while ( lineIter.eot() === false ) {
|
while ( lineIter.eot() === false ) {
|
||||||
if ( lineIter.text.charCodeAt(lineIter.offset) !== 0x63 /* 'c' */ ) {
|
line = lineIter.next();
|
||||||
|
if ( line.charCodeAt(0) !== 0x63 /* 'c' */ ) {
|
||||||
|
lineIter.rewind();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
line = lineIter.next();
|
|
||||||
|
|
||||||
this.acceptedCount += 1;
|
this.acceptedCount += 1;
|
||||||
if ( this.duplicateBuster.has(line) ) {
|
if ( this.duplicateBuster.has(line) ) {
|
||||||
|
@ -1078,6 +1078,17 @@ FilterBucket.prototype.add = function(a) {
|
|||||||
this.filters.push(a);
|
this.filters.push(a);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FilterBucket.prototype.remove = function(fclass, fdata) {
|
||||||
|
var i = this.filters.length,
|
||||||
|
filter;
|
||||||
|
while ( i-- ) {
|
||||||
|
filter = this.filters[i];
|
||||||
|
if ( filter.fid === fclass && filter.toSelfie() === fdata ) {
|
||||||
|
this.filters.splice(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Promote hit filters so they can be found faster next time.
|
// Promote hit filters so they can be found faster next time.
|
||||||
FilterBucket.prototype.promote = function(i) {
|
FilterBucket.prototype.promote = function(i) {
|
||||||
var filters = this.filters;
|
var filters = this.filters;
|
||||||
@ -1181,6 +1192,7 @@ FilterParser.prototype.toNormalizedType = {
|
|||||||
FilterParser.prototype.reset = function() {
|
FilterParser.prototype.reset = function() {
|
||||||
this.action = BlockAction;
|
this.action = BlockAction;
|
||||||
this.anchor = 0;
|
this.anchor = 0;
|
||||||
|
this.badFilter = false;
|
||||||
this.elemHiding = false;
|
this.elemHiding = false;
|
||||||
this.f = '';
|
this.f = '';
|
||||||
this.firstParty = false;
|
this.firstParty = false;
|
||||||
@ -1334,6 +1346,11 @@ FilterParser.prototype.parseOptions = function(s) {
|
|||||||
if ( opt === 'empty' ) {
|
if ( opt === 'empty' ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// https://github.com/uBlockOrigin/uAssets/issues/192
|
||||||
|
if ( opt === 'badfilter' ) {
|
||||||
|
this.badFilter = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// Unrecognized filter option: ignore whole filter.
|
// Unrecognized filter option: ignore whole filter.
|
||||||
this.unsupported = true;
|
this.unsupported = true;
|
||||||
break;
|
break;
|
||||||
@ -1598,10 +1615,10 @@ FilterContainer.prototype.reset = function() {
|
|||||||
this.allowFilterCount = 0;
|
this.allowFilterCount = 0;
|
||||||
this.blockFilterCount = 0;
|
this.blockFilterCount = 0;
|
||||||
this.discardedCount = 0;
|
this.discardedCount = 0;
|
||||||
|
this.badFilters = new Set();
|
||||||
this.duplicateBuster = new Set();
|
this.duplicateBuster = new Set();
|
||||||
this.categories = new Map();
|
this.categories = new Map();
|
||||||
this.filterParser.reset();
|
this.filterParser.reset();
|
||||||
this.filterCounts = {};
|
|
||||||
|
|
||||||
// Reuse filter instances whenever possible at load time.
|
// Reuse filter instances whenever possible at load time.
|
||||||
this.fclassLast = null;
|
this.fclassLast = null;
|
||||||
@ -1618,6 +1635,7 @@ FilterContainer.prototype.reset = function() {
|
|||||||
|
|
||||||
FilterContainer.prototype.freeze = function() {
|
FilterContainer.prototype.freeze = function() {
|
||||||
histogram('allFilters', this.categories);
|
histogram('allFilters', this.categories);
|
||||||
|
this.removeBadFilters();
|
||||||
this.duplicateBuster = new Set();
|
this.duplicateBuster = new Set();
|
||||||
this.filterParser.reset();
|
this.filterParser.reset();
|
||||||
this.fclassLast = null;
|
this.fclassLast = null;
|
||||||
@ -1853,7 +1871,7 @@ FilterContainer.prototype.compile = function(raw, out) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pure hostnames, use more efficient liquid dict
|
// Pure hostnames, use more efficient dictionary lookup
|
||||||
// https://github.com/chrisaljoudi/uBlock/issues/665
|
// https://github.com/chrisaljoudi/uBlock/issues/665
|
||||||
// Create a dict keyed on request type etc.
|
// Create a dict keyed on request type etc.
|
||||||
if ( parsed.hostnamePure && this.compileHostnameOnlyFilter(parsed, out) ) {
|
if ( parsed.hostnamePure && this.compileHostnameOnlyFilter(parsed, out) ) {
|
||||||
@ -1880,8 +1898,11 @@ FilterContainer.prototype.compileHostnameOnlyFilter = function(parsed, out) {
|
|||||||
// return;
|
// return;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
var party = AnyParty;
|
var route = parsed.badFilter ? 'n-\v' : 'n\v',
|
||||||
if ( parsed.firstParty !== parsed.thirdParty ) {
|
party;
|
||||||
|
if ( parsed.firstParty === parsed.thirdParty ) {
|
||||||
|
party = AnyParty;
|
||||||
|
} else {
|
||||||
party = parsed.firstParty ? FirstParty : ThirdParty;
|
party = parsed.firstParty ? FirstParty : ThirdParty;
|
||||||
}
|
}
|
||||||
var keyShard = parsed.action | parsed.important | party;
|
var keyShard = parsed.action | parsed.important | party;
|
||||||
@ -1889,7 +1910,7 @@ FilterContainer.prototype.compileHostnameOnlyFilter = function(parsed, out) {
|
|||||||
var type = parsed.types;
|
var type = parsed.types;
|
||||||
if ( type === 0 ) {
|
if ( type === 0 ) {
|
||||||
out.push(
|
out.push(
|
||||||
'n\v' +
|
route +
|
||||||
toHex(keyShard) + '\v' +
|
toHex(keyShard) + '\v' +
|
||||||
'.\v' +
|
'.\v' +
|
||||||
parsed.f
|
parsed.f
|
||||||
@ -1901,7 +1922,7 @@ FilterContainer.prototype.compileHostnameOnlyFilter = function(parsed, out) {
|
|||||||
do {
|
do {
|
||||||
if ( type & 1 ) {
|
if ( type & 1 ) {
|
||||||
out.push(
|
out.push(
|
||||||
'n\v' +
|
route +
|
||||||
toHex(keyShard | (bitOffset << 4)) + '\v' +
|
toHex(keyShard | (bitOffset << 4)) + '\v' +
|
||||||
'.\v' +
|
'.\v' +
|
||||||
parsed.f
|
parsed.f
|
||||||
@ -1934,11 +1955,12 @@ FilterContainer.prototype.compileFilter = function(parsed, out) {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
FilterContainer.prototype.compileToAtomicFilter = function(filterClass, parsed, party, out) {
|
FilterContainer.prototype.compileToAtomicFilter = function(filterClass, parsed, party, out) {
|
||||||
var bits = parsed.action | parsed.important | party;
|
var route = parsed.badFilter ? 'n-\v' : 'n\v',
|
||||||
var type = parsed.types;
|
bits = parsed.action | parsed.important | party,
|
||||||
|
type = parsed.types;
|
||||||
if ( type === 0 ) {
|
if ( type === 0 ) {
|
||||||
out.push(
|
out.push(
|
||||||
'n\v' +
|
route +
|
||||||
toHex(bits) + '\v' +
|
toHex(bits) + '\v' +
|
||||||
parsed.token + '\v' +
|
parsed.token + '\v' +
|
||||||
filterClass.fid + '\v' +
|
filterClass.fid + '\v' +
|
||||||
@ -1950,7 +1972,7 @@ FilterContainer.prototype.compileToAtomicFilter = function(filterClass, parsed,
|
|||||||
do {
|
do {
|
||||||
if ( type & 1 ) {
|
if ( type & 1 ) {
|
||||||
out.push(
|
out.push(
|
||||||
'n\v' +
|
route +
|
||||||
toHex(bits | (bitOffset << 4)) + '\v' +
|
toHex(bits | (bitOffset << 4)) + '\v' +
|
||||||
parsed.token + '\v' +
|
parsed.token + '\v' +
|
||||||
filterClass.fid + '\v' +
|
filterClass.fid + '\v' +
|
||||||
@ -1967,6 +1989,10 @@ FilterContainer.prototype.compileToAtomicFilter = function(filterClass, parsed,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( parsed.badFilter ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var redirects = µb.redirectEngine.compileRuleFromStaticFilter(parsed.raw);
|
var redirects = µb.redirectEngine.compileRuleFromStaticFilter(parsed.raw);
|
||||||
if ( Array.isArray(redirects) === false ) {
|
if ( Array.isArray(redirects) === false ) {
|
||||||
return;
|
return;
|
||||||
@ -1985,12 +2011,17 @@ FilterContainer.prototype.fromCompiledContent = function(lineIter) {
|
|||||||
fieldIter = new µb.FieldIterator('\v');
|
fieldIter = new µb.FieldIterator('\v');
|
||||||
|
|
||||||
while ( lineIter.eot() === false ) {
|
while ( lineIter.eot() === false ) {
|
||||||
if ( lineIter.text.charCodeAt(lineIter.offset) !== 0x6E /* 'n' */ ) {
|
line = lineIter.next();
|
||||||
|
if ( line.charCodeAt(0) !== 0x6E /* 'n' */ ) {
|
||||||
|
lineIter.rewind();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
line = lineIter.next();
|
|
||||||
|
|
||||||
fieldIter.first(line);
|
if ( fieldIter.first(line) === 'n-' ) {
|
||||||
|
this.badFilters.add(line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
hash = fieldIter.next();
|
hash = fieldIter.next();
|
||||||
token = fieldIter.next();
|
token = fieldIter.next();
|
||||||
fclass = fieldIter.next();
|
fclass = fieldIter.next();
|
||||||
@ -2046,6 +2077,47 @@ FilterContainer.prototype.fromCompiledContent = function(lineIter) {
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
FilterContainer.prototype.removeBadFilters = function() {
|
||||||
|
var lines = µb.setToArray(this.badFilters),
|
||||||
|
fieldIter = new µb.FieldIterator('\v'),
|
||||||
|
hash, token, fclass, fdata, bucket, entry,
|
||||||
|
i = lines.length;
|
||||||
|
while ( i-- ) {
|
||||||
|
fieldIter.first(lines[i]);
|
||||||
|
hash = fieldIter.next();
|
||||||
|
token = fieldIter.next();
|
||||||
|
fclass = fieldIter.next();
|
||||||
|
fdata = fieldIter.next();
|
||||||
|
bucket = this.categories.get(hash);
|
||||||
|
if ( bucket === undefined ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
entry = bucket.get(token);
|
||||||
|
if ( entry === undefined ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( entry instanceof FilterHostnameDict ) {
|
||||||
|
entry.delete(fclass); // 'fclass' is hostname
|
||||||
|
if ( entry.dict.size === 0 ) {
|
||||||
|
this.categories.delete(hash);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( entry instanceof FilterBucket ) {
|
||||||
|
entry.remove(fclass, fdata);
|
||||||
|
if ( entry.filters.length === 1 ) {
|
||||||
|
bucket.set(token, entry.filters[0]);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( entry.fid === fclass && entry.toSelfie() === fdata ) {
|
||||||
|
this.categories.delete(hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
FilterContainer.prototype.filterStringFromCompiled = function(compiled) {
|
FilterContainer.prototype.filterStringFromCompiled = function(compiled) {
|
||||||
var opts = [];
|
var opts = [];
|
||||||
var vfields = compiled.split('\v');
|
var vfields = compiled.split('\v');
|
||||||
|
@ -163,6 +163,20 @@
|
|||||||
return line;
|
return line;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
µBlock.LineIterator.prototype.rewind = function() {
|
||||||
|
if ( this.offset <= 1 ) {
|
||||||
|
this.offset = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var lineEnd = this.text.lastIndexOf('\n', this.offset - 2);
|
||||||
|
if ( lineEnd !== -1 ) {
|
||||||
|
this.offset = lineEnd + 1;
|
||||||
|
} else {
|
||||||
|
lineEnd = this.text.lastIndexOf('\r', this.offset - 2);
|
||||||
|
this.offset = lineEnd !== -1 ? lineEnd + 1 : 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
µBlock.LineIterator.prototype.eot = function() {
|
µBlock.LineIterator.prototype.eot = function() {
|
||||||
return this.offset >= this.textLen;
|
return this.offset >= this.textLen;
|
||||||
};
|
};
|
||||||
@ -197,33 +211,37 @@
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
µBlock.mapToArray = function(map) {
|
µBlock.mapToArray = typeof Array.from === 'function'
|
||||||
var out = [],
|
? Array.from
|
||||||
entries = map.entries(),
|
: function(map) {
|
||||||
entry;
|
var out = [],
|
||||||
for (;;) {
|
entries = map.entries(),
|
||||||
entry = entries.next();
|
entry;
|
||||||
if ( entry.done ) { break; }
|
for (;;) {
|
||||||
out.push([ entry.value[0], entry.value[1] ]);
|
entry = entries.next();
|
||||||
}
|
if ( entry.done ) { break; }
|
||||||
return out;
|
out.push([ entry.value[0], entry.value[1] ]);
|
||||||
};
|
}
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
|
||||||
µBlock.mapFromArray = function(arr) {
|
µBlock.mapFromArray = function(arr) {
|
||||||
return new Map(arr);
|
return new Map(arr);
|
||||||
};
|
};
|
||||||
|
|
||||||
µBlock.setToArray = function(dict) {
|
µBlock.setToArray = typeof Array.from === 'function'
|
||||||
var out = [],
|
? Array.from
|
||||||
entries = dict.values(),
|
: function(dict) {
|
||||||
entry;
|
var out = [],
|
||||||
for (;;) {
|
entries = dict.values(),
|
||||||
entry = entries.next();
|
entry;
|
||||||
if ( entry.done ) { break; }
|
for (;;) {
|
||||||
out.push(entry.value);
|
entry = entries.next();
|
||||||
}
|
if ( entry.done ) { break; }
|
||||||
return out;
|
out.push(entry.value);
|
||||||
};
|
}
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
|
||||||
µBlock.setFromArray = function(arr) {
|
µBlock.setFromArray = function(arr) {
|
||||||
return new Set(arr);
|
return new Set(arr);
|
||||||
|
Loading…
Reference in New Issue
Block a user