Skip to content

Commit 1caff74

Browse files
committed
Add optional support for generic procedural cosmetic filters
Related issue: - uBlockOrigin/uBlock-issues#131 The new advanced setting and its default value is: allowGenericProceduralFilters false Whenever this setting is toggled, the user is responsible of forcing a reload of all filter lists so as to allow uBO to process differently any existing generic procedural cosmetic filters.
1 parent e66e449 commit 1caff74

File tree

2 files changed

+24
-43
lines changed

2 files changed

+24
-43
lines changed

src/js/background.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ if ( vAPI.webextFlavor === undefined ) {
3636
const µBlock = (function() { // jshint ignore:line
3737

3838
const hiddenSettingsDefault = {
39+
allowGenericProceduralFilters: false,
3940
assetFetchTimeout: 30,
4041
autoCommentFilterTemplate: '{{date}} {{origin}}',
4142
autoUpdateAssetFetchPeriod: 120,
@@ -54,7 +55,7 @@ const µBlock = (function() { // jshint ignore:line
5455
selfieAfter: 3,
5556
strictBlockingBypassDuration: 120,
5657
suspendTabsUntilReady: 'unset',
57-
userResourcesLocation: 'unset'
58+
userResourcesLocation: 'unset',
5859
};
5960

6061
return {
@@ -135,7 +136,7 @@ const µBlock = (function() { // jshint ignore:line
135136

136137
// Read-only
137138
systemSettings: {
138-
compiledMagic: 15, // Increase when compiled format changes
139+
compiledMagic: 16, // Increase when compiled format changes
139140
selfieMagic: 16 // Increase when selfie format changes
140141
},
141142

src/js/cosmetic-filtering.js

Lines changed: 21 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ const SelectorCacheEntry = class {
6262
}
6363

6464
addCosmetic(details) {
65-
let selectors = details.selectors,
66-
i = selectors.length || 0;
65+
const selectors = details.selectors;
66+
let i = selectors.length || 0;
6767
// https://github.com/gorhill/uBlock/issues/2011
6868
// Avoiding seemingly pointless surveys only if they appear costly.
6969
if ( details.first && i === 0 ) {
@@ -90,8 +90,8 @@ const SelectorCacheEntry = class {
9090
if ( this.net.size < SelectorCacheEntry.netHighWaterMark ) {
9191
return;
9292
}
93-
let dict = this.net;
94-
let keys = Array.from(dict.keys()).sort(function(a, b) {
93+
const dict = this.net;
94+
const keys = Array.from(dict.keys()).sort(function(a, b) {
9595
return dict.get(b) - dict.get(a);
9696
}).slice(SelectorCacheEntry.netLowWaterMark);
9797
let i = keys.length;
@@ -146,7 +146,7 @@ const SelectorCacheEntry = class {
146146

147147
retrieve(type, out) {
148148
this.lastAccessTime = Date.now();
149-
let iterator = type === 'cosmetic' ? this.cosmetic : this.net.keys();
149+
const iterator = type === 'cosmetic' ? this.cosmetic : this.net.keys();
150150
if ( Array.isArray(out) ) {
151151
this.retrieveToArray(iterator, out);
152152
} else {
@@ -201,9 +201,6 @@ const FilterContainer = function() {
201201
this.netSelectorCacheCountMax = SelectorCacheEntry.netHighWaterMark;
202202
this.selectorCacheTimer = null;
203203

204-
// generic exception filters
205-
this.genericDonthideSet = new Set();
206-
207204
// specific filters
208205
this.specificFilters = new µb.staticExtFilteringEngine.HostnameBasedDB(2);
209206

@@ -269,9 +266,6 @@ FilterContainer.prototype.reset = function() {
269266
// generic filters
270267
this.hasGenericHide = false;
271268

272-
// generic exception filters
273-
this.genericDonthideSet.clear();
274-
275269
// hostname, entity-based filters
276270
this.specificFilters.clear();
277271

@@ -312,7 +306,6 @@ FilterContainer.prototype.freeze = function() {
312306
this.frozen = true;
313307
};
314308

315-
316309
/******************************************************************************/
317310

318311
// https://github.com/gorhill/uBlock/issues/1668
@@ -429,11 +422,17 @@ FilterContainer.prototype.compileGenericHideSelector = function(
429422
// https://github.com/uBlockOrigin/uBlock-issues/issues/464
430423
// Pseudoclass-based selectors can be compiled, but are also valid
431424
// plain selectors.
425+
// https://github.com/uBlockOrigin/uBlock-issues/issues/131
426+
// Support generic procedural filters as per advanced settings.
427+
// TODO: prevent double compilation.
432428
if (
433429
compiled === undefined ||
434430
compiled !== selector &&
435431
µb.staticExtFilteringEngine.compileSelector.pseudoclass !== true
436432
) {
433+
if ( µb.hiddenSettings.allowGenericProceduralFilters === true ) {
434+
return this.compileSpecificSelector('', parsed, writer);
435+
}
437436
const who = writer.properties.get('assetKey') || '?';
438437
µb.logger.writeOne({
439438
realm: 'message',
@@ -450,8 +449,8 @@ FilterContainer.prototype.compileGenericHideSelector = function(
450449
writer.push([
451450
type === 0x23 /* '#' */ ? 1 : 3,
452451
key.slice(1),
453-
selector ]
454-
);
452+
selector
453+
]);
455454
return;
456455
}
457456

@@ -493,7 +492,7 @@ FilterContainer.prototype.compileGenericUnhideSelector = function(
493492
writer
494493
) {
495494
// Procedural cosmetic filters are acceptable as generic exception filters.
496-
let compiled = µb.staticExtFilteringEngine.compileSelector(parsed.suffix);
495+
const compiled = µb.staticExtFilteringEngine.compileSelector(parsed.suffix);
497496
if ( compiled === undefined ) {
498497
const who = writer.properties.get('assetKey') || '?';
499498
µb.logger.writeOne({
@@ -505,9 +504,12 @@ FilterContainer.prototype.compileGenericUnhideSelector = function(
505504
}
506505

507506
// https://github.com/chrisaljoudi/uBlock/issues/497
508-
// All generic exception filters are put in the same bucket: they are
509-
// expected to be very rare.
510-
writer.push([ 7 /* g1 */, compiled ]);
507+
// All generic exception filters are stored as hostname-based filter
508+
// whereas the hostname is the empty string (which matches all
509+
// hostnames). No distinction is made between declarative and
510+
// procedural selectors, since they really exist only to cancel
511+
// out other cosmetic filters.
512+
writer.push([ 8, '', 0b01, compiled ]);
511513
};
512514

513515
/******************************************************************************/
@@ -622,13 +624,6 @@ FilterContainer.prototype.fromCompiledContent = function(reader, options) {
622624
this.highlyGeneric.complex.dict.add(args[1]);
623625
break;
624626

625-
// https://github.com/chrisaljoudi/uBlock/issues/497
626-
// Generic exception filters: expected to be a rare occurrence.
627-
// #@#.tweet
628-
case 7:
629-
this.genericDonthideSet.add(args[1]);
630-
break;
631-
632627
// hash, example.com, .promoted-tweet
633628
// hash, example.*, .promoted-tweet
634629
case 8:
@@ -660,13 +655,6 @@ FilterContainer.prototype.skipGenericCompiledContent = function(reader) {
660655

661656
switch ( args[0] ) {
662657

663-
// https://github.com/chrisaljoudi/uBlock/issues/497
664-
// Generic exception filters: expected to be a rare occurrence.
665-
case 7:
666-
this.duplicateBuster.add(fingerprint);
667-
this.genericDonthideSet.add(args[1]);
668-
break;
669-
670658
// hash, example.com, .promoted-tweet
671659
// hash, example.*, .promoted-tweet
672660
case 8:
@@ -707,7 +695,6 @@ FilterContainer.prototype.toSelfie = function() {
707695
lowlyGenericCCL: Array.from(this.lowlyGeneric.cl.complex),
708696
highSimpleGenericHideArray: Array.from(this.highlyGeneric.simple.dict),
709697
highComplexGenericHideArray: Array.from(this.highlyGeneric.complex.dict),
710-
genericDonthideArray: Array.from(this.genericDonthideSet)
711698
};
712699
};
713700

@@ -726,7 +713,6 @@ FilterContainer.prototype.fromSelfie = function(selfie) {
726713
this.highlyGeneric.simple.str = selfie.highSimpleGenericHideArray.join(',\n');
727714
this.highlyGeneric.complex.dict = new Set(selfie.highComplexGenericHideArray);
728715
this.highlyGeneric.complex.str = selfie.highComplexGenericHideArray.join(',\n');
729-
this.genericDonthideSet = new Set(selfie.genericDonthideArray);
730716
this.frozen = true;
731717
};
732718

@@ -989,13 +975,6 @@ FilterContainer.prototype.retrieveSpecificSelectors = function(
989975
};
990976

991977
if ( options.noCosmeticFiltering !== true ) {
992-
// Exception cosmetic filters: prime with generic exception filters.
993-
const exceptionSet = this.setRegister0;
994-
// Genetic exceptions (should be extremely rare).
995-
for ( let exception of this.genericDonthideSet ) {
996-
exceptionSet.add(exception);
997-
}
998-
999978
const specificSet = this.setRegister1;
1000979
// Cached cosmetic filters: these are always declarative.
1001980
if ( cacheEntry !== undefined ) {
@@ -1006,6 +985,7 @@ FilterContainer.prototype.retrieveSpecificSelectors = function(
1006985
}
1007986
}
1008987

988+
const exceptionSet = this.setRegister0;
1009989
const proceduralSet = this.setRegister2;
1010990

1011991
this.specificFilters.retrieve(

0 commit comments

Comments
 (0)