mirror of
https://github.com/gorhill/uBlock.git
synced 2024-11-10 09:07:54 +01:00
Ensure compiled sections are ordered in ascending id
Related issue: - https://www.reddit.com/r/uBlockOrigin/comments/oq6kt5/ubo_loads_generic_filter_instead_of_specific/h6a4nca/
This commit is contained in:
parent
2035475371
commit
c25938f5bc
2 changed files with 87 additions and 107 deletions
|
@ -32,6 +32,9 @@ const cosmeticSurveyingMissCountMax =
|
||||||
parseInt(vAPI.localStorage.getItem('cosmeticSurveyingMissCountMax'), 10) ||
|
parseInt(vAPI.localStorage.getItem('cosmeticSurveyingMissCountMax'), 10) ||
|
||||||
15;
|
15;
|
||||||
|
|
||||||
|
const COMPILED_SPECIFIC_SECTION = 0;
|
||||||
|
const COMPILED_GENERIC_SECTION = 1;
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
@ -340,8 +343,6 @@ FilterContainer.prototype.keyFromSelector = function(selector) {
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
FilterContainer.prototype.compile = function(parser, writer) {
|
FilterContainer.prototype.compile = function(parser, writer) {
|
||||||
writer.select(µb.compiledCosmeticSection);
|
|
||||||
|
|
||||||
if ( parser.hasOptions() === false ) {
|
if ( parser.hasOptions() === false ) {
|
||||||
this.compileGenericSelector(parser, writer);
|
this.compileGenericSelector(parser, writer);
|
||||||
return true;
|
return true;
|
||||||
|
@ -368,6 +369,7 @@ FilterContainer.prototype.compile = function(parser, writer) {
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
FilterContainer.prototype.compileGenericSelector = function(parser, writer) {
|
FilterContainer.prototype.compileGenericSelector = function(parser, writer) {
|
||||||
|
writer.select(µb.compiledCosmeticSection + COMPILED_GENERIC_SECTION);
|
||||||
if ( parser.isException() ) {
|
if ( parser.isException() ) {
|
||||||
this.compileGenericUnhideSelector(parser, writer);
|
this.compileGenericUnhideSelector(parser, writer);
|
||||||
} else {
|
} else {
|
||||||
|
@ -509,6 +511,7 @@ FilterContainer.prototype.compileSpecificSelector = function(
|
||||||
not,
|
not,
|
||||||
writer
|
writer
|
||||||
) {
|
) {
|
||||||
|
writer.select(µb.compiledCosmeticSection + COMPILED_SPECIFIC_SECTION);
|
||||||
const { raw, compiled, exception } = parser.result;
|
const { raw, compiled, exception } = parser.result;
|
||||||
if ( compiled === undefined ) {
|
if ( compiled === undefined ) {
|
||||||
const who = writer.properties.get('assetKey') || '?';
|
const who = writer.properties.get('assetKey') || '?';
|
||||||
|
@ -551,18 +554,13 @@ FilterContainer.prototype.compileTemporary = function(parser) {
|
||||||
|
|
||||||
FilterContainer.prototype.fromCompiledContent = function(reader, options) {
|
FilterContainer.prototype.fromCompiledContent = function(reader, options) {
|
||||||
if ( options.skipCosmetic ) {
|
if ( options.skipCosmetic ) {
|
||||||
this.skipCompiledContent(reader);
|
this.skipCompiledContent(reader, COMPILED_SPECIFIC_SECTION);
|
||||||
return;
|
this.skipCompiledContent(reader, COMPILED_GENERIC_SECTION);
|
||||||
}
|
|
||||||
if ( options.skipGenericCosmetic ) {
|
|
||||||
this.skipGenericCompiledContent(reader);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reader.select(µb.compiledCosmeticSection);
|
// Specific cosmetic filter section
|
||||||
|
reader.select(µb.compiledCosmeticSection + COMPILED_SPECIFIC_SECTION);
|
||||||
let db, bucket;
|
|
||||||
|
|
||||||
while ( reader.next() ) {
|
while ( reader.next() ) {
|
||||||
this.acceptedCount += 1;
|
this.acceptedCount += 1;
|
||||||
const fingerprint = reader.fingerprint();
|
const fingerprint = reader.fingerprint();
|
||||||
|
@ -571,56 +569,8 @@ FilterContainer.prototype.fromCompiledContent = function(reader, options) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
this.duplicateBuster.add(fingerprint);
|
this.duplicateBuster.add(fingerprint);
|
||||||
|
|
||||||
const args = reader.args();
|
const args = reader.args();
|
||||||
|
|
||||||
switch ( args[0] ) {
|
switch ( args[0] ) {
|
||||||
|
|
||||||
// low generic, simple
|
|
||||||
case 0: // #AdBanner
|
|
||||||
case 2: // .largeAd
|
|
||||||
db = args[0] === 0 ? this.lowlyGeneric.id : this.lowlyGeneric.cl;
|
|
||||||
bucket = db.complex.get(args[1]);
|
|
||||||
if ( bucket === undefined ) {
|
|
||||||
db.simple.add(args[1]);
|
|
||||||
} else if ( Array.isArray(bucket) ) {
|
|
||||||
bucket.push(db.prefix + args[1]);
|
|
||||||
} else {
|
|
||||||
db.complex.set(args[1], [ bucket, db.prefix + args[1] ]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// low generic, complex
|
|
||||||
case 1: // #tads + div + .c
|
|
||||||
case 3: // .Mpopup + #Mad > #MadZone
|
|
||||||
db = args[0] === 1 ? this.lowlyGeneric.id : this.lowlyGeneric.cl;
|
|
||||||
bucket = db.complex.get(args[1]);
|
|
||||||
if ( bucket === undefined ) {
|
|
||||||
if ( db.simple.has(args[1]) ) {
|
|
||||||
db.complex.set(args[1], [ db.prefix + args[1], args[2] ]);
|
|
||||||
} else {
|
|
||||||
db.complex.set(args[1], args[2]);
|
|
||||||
db.simple.add(args[1]);
|
|
||||||
}
|
|
||||||
} else if ( Array.isArray(bucket) ) {
|
|
||||||
bucket.push(args[2]);
|
|
||||||
} else {
|
|
||||||
db.complex.set(args[1], [ bucket, args[2] ]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// High-high generic hide/simple selectors
|
|
||||||
// div[id^="allo"]
|
|
||||||
case 4:
|
|
||||||
this.highlyGeneric.simple.dict.add(args[1]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// High-high generic hide/complex selectors
|
|
||||||
// div[id^="allo"] > span
|
|
||||||
case 5:
|
|
||||||
this.highlyGeneric.complex.dict.add(args[1]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// hash, example.com, .promoted-tweet
|
// hash, example.com, .promoted-tweet
|
||||||
// hash, example.*, .promoted-tweet
|
// hash, example.*, .promoted-tweet
|
||||||
//
|
//
|
||||||
|
@ -639,19 +589,19 @@ FilterContainer.prototype.fromCompiledContent = function(reader, options) {
|
||||||
}
|
}
|
||||||
this.specificFilters.store(args[1], args[2] & 0b011, args[3]);
|
this.specificFilters.store(args[1], args[2] & 0b011, args[3]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
this.discardedCount += 1;
|
this.discardedCount += 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
if ( options.skipGenericCosmetic ) {
|
||||||
|
this.skipCompiledContent(reader, COMPILED_GENERIC_SECTION);
|
||||||
FilterContainer.prototype.skipGenericCompiledContent = function(reader) {
|
return;
|
||||||
reader.select(µb.compiledCosmeticSection);
|
}
|
||||||
|
|
||||||
|
// Generic cosmetic filter section
|
||||||
|
reader.select(µb.compiledCosmeticSection + COMPILED_GENERIC_SECTION);
|
||||||
while ( reader.next() ) {
|
while ( reader.next() ) {
|
||||||
this.acceptedCount += 1;
|
this.acceptedCount += 1;
|
||||||
const fingerprint = reader.fingerprint();
|
const fingerprint = reader.fingerprint();
|
||||||
|
@ -659,28 +609,52 @@ FilterContainer.prototype.skipGenericCompiledContent = function(reader) {
|
||||||
this.discardedCount += 1;
|
this.discardedCount += 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const args = reader.args();
|
|
||||||
|
|
||||||
switch ( args[0] ) {
|
|
||||||
|
|
||||||
// https://github.com/uBlockOrigin/uBlock-issues/issues/803
|
|
||||||
// Handle specific filters meant to apply everywhere, i.e. selectors
|
|
||||||
// not to be injected conditionally through the DOM surveyor.
|
|
||||||
// hash, *, .promoted-tweet
|
|
||||||
case 8:
|
|
||||||
this.duplicateBuster.add(fingerprint);
|
this.duplicateBuster.add(fingerprint);
|
||||||
if ( args[2] === 0b100 ) {
|
const args = reader.args();
|
||||||
if ( this.reSimpleHighGeneric.test(args[3]) )
|
switch ( args[0] ) {
|
||||||
this.highlyGeneric.simple.dict.add(args[3]);
|
// low generic, simple
|
||||||
else {
|
case 0: // #AdBanner
|
||||||
this.highlyGeneric.complex.dict.add(args[3]);
|
case 2: { // .largeAd
|
||||||
|
const db = args[0] === 0 ? this.lowlyGeneric.id : this.lowlyGeneric.cl;
|
||||||
|
const bucket = db.complex.get(args[1]);
|
||||||
|
if ( bucket === undefined ) {
|
||||||
|
db.simple.add(args[1]);
|
||||||
|
} else if ( Array.isArray(bucket) ) {
|
||||||
|
bucket.push(db.prefix + args[1]);
|
||||||
|
} else {
|
||||||
|
db.complex.set(args[1], [ bucket, db.prefix + args[1] ]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this.specificFilters.store(args[1], args[2] & 0b011, args[3]);
|
// low generic, complex
|
||||||
|
case 1: // #tads + div + .c
|
||||||
|
case 3: { // .Mpopup + #Mad > #MadZone
|
||||||
|
const db = args[0] === 1 ? this.lowlyGeneric.id : this.lowlyGeneric.cl;
|
||||||
|
const bucket = db.complex.get(args[1]);
|
||||||
|
if ( bucket === undefined ) {
|
||||||
|
if ( db.simple.has(args[1]) ) {
|
||||||
|
db.complex.set(args[1], [ db.prefix + args[1], args[2] ]);
|
||||||
|
} else {
|
||||||
|
db.complex.set(args[1], args[2]);
|
||||||
|
db.simple.add(args[1]);
|
||||||
|
}
|
||||||
|
} else if ( Array.isArray(bucket) ) {
|
||||||
|
bucket.push(args[2]);
|
||||||
|
} else {
|
||||||
|
db.complex.set(args[1], [ bucket, args[2] ]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// High-high generic hide/simple selectors
|
||||||
|
// div[id^="allo"]
|
||||||
|
case 4:
|
||||||
|
this.highlyGeneric.simple.dict.add(args[1]);
|
||||||
|
break;
|
||||||
|
// High-high generic hide/complex selectors
|
||||||
|
// div[id^="allo"] > span
|
||||||
|
case 5:
|
||||||
|
this.highlyGeneric.complex.dict.add(args[1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
this.discardedCount += 1;
|
this.discardedCount += 1;
|
||||||
break;
|
break;
|
||||||
|
@ -690,9 +664,8 @@ FilterContainer.prototype.skipGenericCompiledContent = function(reader) {
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
FilterContainer.prototype.skipCompiledContent = function(reader) {
|
FilterContainer.prototype.skipCompiledContent = function(reader, sectionId) {
|
||||||
reader.select(µb.compiledCosmeticSection);
|
reader.select(µb.compiledCosmeticSection + sectionId);
|
||||||
|
|
||||||
while ( reader.next() ) {
|
while ( reader.next() ) {
|
||||||
this.acceptedCount += 1;
|
this.acceptedCount += 1;
|
||||||
this.discardedCount += 1;
|
this.discardedCount += 1;
|
||||||
|
|
|
@ -123,6 +123,11 @@
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
// https://www.reddit.com/r/uBlockOrigin/comments/oq6kt5/ubo_loads_generic_filter_instead_of_specific/
|
||||||
|
// Ensure blocks of content are sorted in ascending id order, such that the
|
||||||
|
// specific cosmetic filters will be found (and thus reported) before the
|
||||||
|
// generic ones.
|
||||||
|
|
||||||
µBlock.CompiledLineIO = {
|
µBlock.CompiledLineIO = {
|
||||||
serialize: JSON.stringify,
|
serialize: JSON.stringify,
|
||||||
unserialize: JSON.parse,
|
unserialize: JSON.parse,
|
||||||
|
@ -156,8 +161,10 @@
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
toString() {
|
toString() {
|
||||||
let result = [];
|
const result = [];
|
||||||
for ( let [ id, lines ] of this.blocks ) {
|
const sortedBlocks =
|
||||||
|
Array.from(this.blocks).sort((a, b) => a[0] - b[0]);
|
||||||
|
for ( const [ id, lines ] of sortedBlocks ) {
|
||||||
if ( lines.length === 0 ) { continue; }
|
if ( lines.length === 0 ) { continue; }
|
||||||
result.push(
|
result.push(
|
||||||
this.io.blockStartPrefix + id,
|
this.io.blockStartPrefix + id,
|
||||||
|
|
Loading…
Reference in a new issue