From 6464002088ae656e69f077ece3de877360e22861 Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Wed, 6 Oct 2021 09:44:15 -0400 Subject: [PATCH] Give precedence to negated types in case of ambiguity Related feedback: - https://github.com/uBlockOrigin/uAssets/issues/7639#issuecomment-933525018 --- platform/npm/tests/snfe.js | 14 +++++++++++++- src/js/static-net-filtering.js | 29 +++++++++++++++++++---------- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/platform/npm/tests/snfe.js b/platform/npm/tests/snfe.js index c6de0aeac..173d5f233 100644 --- a/platform/npm/tests/snfe.js +++ b/platform/npm/tests/snfe.js @@ -288,7 +288,7 @@ describe('SNFE', () => { assert(engine.isBlockImportant()); }); - it('should block all except stylesheets', async () => { + it('should block all except stylesheets #1', async () => { await engine.useLists([ { name: 'test', raw: '||example.com^$~stylesheet,all' }, ]); @@ -299,6 +299,18 @@ describe('SNFE', () => { }); assert.strictEqual(r, 0); }); + + it('should block all except stylesheets #2', async () => { + await engine.useLists([ + { name: 'test', raw: '||example.com^$all,~stylesheet' }, + ]); + const r = engine.matchRequest({ + originURL: 'https://www.example.com/', + type: 'stylesheet', + url: 'https://www.example.com/', + }); + assert.strictEqual(r, 0); + }); }); }); } diff --git a/src/js/static-net-filtering.js b/src/js/static-net-filtering.js index ae5f68c7f..68a3a6bf0 100644 --- a/src/js/static-net-filtering.js +++ b/src/js/static-net-filtering.js @@ -2955,15 +2955,20 @@ class FilterCompiler { // Be ready to handle multiple negated types processTypeOption(id, not) { - const typeBit = id !== -1 - ? this.tokenIdToNormalizedType.get(id) - : allTypesBits; + if ( id !== -1 ) { + const typeBit = this.tokenIdToNormalizedType.get(id); + if ( not ) { + this.notTypeBits |= typeBit; + } else { + this.typeBits |= typeBit; + } + return; + } + // `all` option if ( not ) { - this.notTypeBits |= typeBit; - this.typeBits &= ~typeBit; + this.notTypeBits |= allTypesBits; } else { - this.typeBits |= typeBit; - this.notTypeBits &= ~typeBit; + this.typeBits |= allTypesBits; } } @@ -3140,7 +3145,11 @@ class FilterCompiler { // - no network type is present -- i.e. all network types are // implicitly toggled on if ( this.notTypeBits !== 0 ) { - this.typeBits &= ~this.notTypeBits; + if ( (this.typeBits && allNetworkTypesBits) === allNetworkTypesBits ) { + this.typeBits &= ~this.notTypeBits | allNetworkTypesBits; + } else { + this.typeBits &= ~this.notTypeBits; + } this.optionUnitBits |= this.NOT_TYPE_BIT; } @@ -3546,7 +3555,7 @@ class FilterCompiler { compileToAtomicFilter(fdata, writer) { const catBits = this.action | this.party; - let { notTypeBits, typeBits } = this; + let { typeBits } = this; // Typeless if ( typeBits === 0 ) { @@ -3556,7 +3565,7 @@ class FilterCompiler { // If all network types are set, create a typeless filter. Excluded // network types are tested at match time, se we act as if they are // set. - if ( ((typeBits | notTypeBits) & allNetworkTypesBits) === allNetworkTypesBits ) { + if ( (typeBits & allNetworkTypesBits) === allNetworkTypesBits ) { writer.push([ catBits, this.tokenHash, fdata ]); typeBits &= ~allNetworkTypesBits; if ( typeBits === 0 ) { return; }