Skip to content

Commit

Permalink
new filter option: "badfilter" (see uBlockOrigin/uAssets#192)
Browse files Browse the repository at this point in the history
gorhill committed Mar 11, 2017

Verified

This commit was signed with the committer’s verified signature.
gorhill Raymond Hill
1 parent e8375f9 commit a4e20ae
Showing 3 changed files with 134 additions and 41 deletions.
15 changes: 9 additions & 6 deletions src/js/cosmetic-filtering.js
Original file line number Diff line number Diff line change
@@ -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) ) {
98 changes: 85 additions & 13 deletions src/js/static-net-filtering.js
Original file line number Diff line number Diff line change
@@ -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,16 +1898,19 @@ 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;

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');
62 changes: 40 additions & 22 deletions src/js/utils.js
Original file line number Diff line number Diff line change
@@ -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);

0 comments on commit a4e20ae

Please sign in to comment.