1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-11-06 19:02:30 +01:00
This commit is contained in:
gorhill 2017-03-11 13:55:47 -05:00
parent e8375f91cd
commit a4e20ae3ad
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
3 changed files with 134 additions and 41 deletions

View File

@ -1148,10 +1148,11 @@ FilterContainer.prototype.fromCompiledContent = function(lineIter, skipGenericCo
fieldIter = new µb.FieldIterator('\v');
while ( lineIter.eot() === false ) {
if ( lineIter.text.charCodeAt(lineIter.offset) !== 0x63 /* 'c' */ ) {
line = lineIter.next();
if ( line.charCodeAt(0) !== 0x63 /* 'c' */ ) {
lineIter.rewind();
return;
}
line = lineIter.next();
this.acceptedCount += 1;
if ( this.duplicateBuster.has(line) ) {
@ -1274,10 +1275,11 @@ FilterContainer.prototype.skipGenericCompiledContent = function(lineIter) {
fieldIter = new µb.FieldIterator('\v');
while ( lineIter.eot() === false ) {
if ( lineIter.text.charCodeAt(lineIter.offset) !== 0x63 /* 'c' */ ) {
line = lineIter.next();
if ( line.charCodeAt(0) !== 0x63 /* 'c' */ ) {
lineIter.rewind();
return;
}
line = lineIter.next();
this.acceptedCount += 1;
if ( this.duplicateBuster.has(line) ) {
@ -1336,10 +1338,11 @@ FilterContainer.prototype.skipCompiledContent = function(lineIter) {
fieldIter = new µb.FieldIterator('\v');
while ( lineIter.eot() === false ) {
if ( lineIter.text.charCodeAt(lineIter.offset) !== 0x63 /* 'c' */ ) {
line = lineIter.next();
if ( line.charCodeAt(0) !== 0x63 /* 'c' */ ) {
lineIter.rewind();
return;
}
line = lineIter.next();
this.acceptedCount += 1;
if ( this.duplicateBuster.has(line) ) {

View File

@ -1078,6 +1078,17 @@ FilterBucket.prototype.add = function(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.
FilterBucket.prototype.promote = function(i) {
var filters = this.filters;
@ -1181,6 +1192,7 @@ FilterParser.prototype.toNormalizedType = {
FilterParser.prototype.reset = function() {
this.action = BlockAction;
this.anchor = 0;
this.badFilter = false;
this.elemHiding = false;
this.f = '';
this.firstParty = false;
@ -1334,6 +1346,11 @@ FilterParser.prototype.parseOptions = function(s) {
if ( opt === 'empty' ) {
continue;
}
// https://github.com/uBlockOrigin/uAssets/issues/192
if ( opt === 'badfilter' ) {
this.badFilter = true;
continue;
}
// Unrecognized filter option: ignore whole filter.
this.unsupported = true;
break;
@ -1598,10 +1615,10 @@ FilterContainer.prototype.reset = function() {
this.allowFilterCount = 0;
this.blockFilterCount = 0;
this.discardedCount = 0;
this.badFilters = new Set();
this.duplicateBuster = new Set();
this.categories = new Map();
this.filterParser.reset();
this.filterCounts = {};
// Reuse filter instances whenever possible at load time.
this.fclassLast = null;
@ -1618,6 +1635,7 @@ FilterContainer.prototype.reset = function() {
FilterContainer.prototype.freeze = function() {
histogram('allFilters', this.categories);
this.removeBadFilters();
this.duplicateBuster = new Set();
this.filterParser.reset();
this.fclassLast = null;
@ -1853,7 +1871,7 @@ FilterContainer.prototype.compile = function(raw, out) {
return false;
}
// Pure hostnames, use more efficient liquid dict
// Pure hostnames, use more efficient dictionary lookup
// https://github.com/chrisaljoudi/uBlock/issues/665
// Create a dict keyed on request type etc.
if ( parsed.hostnamePure && this.compileHostnameOnlyFilter(parsed, out) ) {
@ -1880,8 +1898,11 @@ FilterContainer.prototype.compileHostnameOnlyFilter = function(parsed, out) {
// return;
//}
var party = AnyParty;
if ( parsed.firstParty !== parsed.thirdParty ) {
var route = parsed.badFilter ? 'n-\v' : 'n\v',
party;
if ( parsed.firstParty === parsed.thirdParty ) {
party = AnyParty;
} else {
party = parsed.firstParty ? FirstParty : ThirdParty;
}
var keyShard = parsed.action | parsed.important | party;
@ -1889,7 +1910,7 @@ FilterContainer.prototype.compileHostnameOnlyFilter = function(parsed, out) {
var type = parsed.types;
if ( type === 0 ) {
out.push(
'n\v' +
route +
toHex(keyShard) + '\v' +
'.\v' +
parsed.f
@ -1901,7 +1922,7 @@ FilterContainer.prototype.compileHostnameOnlyFilter = function(parsed, out) {
do {
if ( type & 1 ) {
out.push(
'n\v' +
route +
toHex(keyShard | (bitOffset << 4)) + '\v' +
'.\v' +
parsed.f
@ -1934,11 +1955,12 @@ FilterContainer.prototype.compileFilter = function(parsed, out) {
/******************************************************************************/
FilterContainer.prototype.compileToAtomicFilter = function(filterClass, parsed, party, out) {
var bits = parsed.action | parsed.important | party;
var type = parsed.types;
var route = parsed.badFilter ? 'n-\v' : 'n\v',
bits = parsed.action | parsed.important | party,
type = parsed.types;
if ( type === 0 ) {
out.push(
'n\v' +
route +
toHex(bits) + '\v' +
parsed.token + '\v' +
filterClass.fid + '\v' +
@ -1950,7 +1972,7 @@ FilterContainer.prototype.compileToAtomicFilter = function(filterClass, parsed,
do {
if ( type & 1 ) {
out.push(
'n\v' +
route +
toHex(bits | (bitOffset << 4)) + '\v' +
parsed.token + '\v' +
filterClass.fid + '\v' +
@ -1967,6 +1989,10 @@ FilterContainer.prototype.compileToAtomicFilter = function(filterClass, parsed,
return;
}
if ( parsed.badFilter ) {
return;
}
var redirects = µb.redirectEngine.compileRuleFromStaticFilter(parsed.raw);
if ( Array.isArray(redirects) === false ) {
return;
@ -1985,12 +2011,17 @@ FilterContainer.prototype.fromCompiledContent = function(lineIter) {
fieldIter = new µb.FieldIterator('\v');
while ( lineIter.eot() === false ) {
if ( lineIter.text.charCodeAt(lineIter.offset) !== 0x6E /* 'n' */ ) {
line = lineIter.next();
if ( line.charCodeAt(0) !== 0x6E /* 'n' */ ) {
lineIter.rewind();
return;
}
line = lineIter.next();
fieldIter.first(line);
if ( fieldIter.first(line) === 'n-' ) {
this.badFilters.add(line);
continue;
}
hash = fieldIter.next();
token = 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) {
var opts = [];
var vfields = compiled.split('\v');

View File

@ -163,6 +163,20 @@
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() {
return this.offset >= this.textLen;
};
@ -197,33 +211,37 @@
/******************************************************************************/
µBlock.mapToArray = function(map) {
var out = [],
entries = map.entries(),
entry;
for (;;) {
entry = entries.next();
if ( entry.done ) { break; }
out.push([ entry.value[0], entry.value[1] ]);
}
return out;
};
µBlock.mapToArray = typeof Array.from === 'function'
? Array.from
: function(map) {
var out = [],
entries = map.entries(),
entry;
for (;;) {
entry = entries.next();
if ( entry.done ) { break; }
out.push([ entry.value[0], entry.value[1] ]);
}
return out;
};
µBlock.mapFromArray = function(arr) {
return new Map(arr);
};
µBlock.setToArray = function(dict) {
var out = [],
entries = dict.values(),
entry;
for (;;) {
entry = entries.next();
if ( entry.done ) { break; }
out.push(entry.value);
}
return out;
};
µBlock.setToArray = typeof Array.from === 'function'
? Array.from
: function(dict) {
var out = [],
entries = dict.values(),
entry;
for (;;) {
entry = entries.next();
if ( entry.done ) { break; }
out.push(entry.value);
}
return out;
};
µBlock.setFromArray = function(arr) {
return new Set(arr);