mirror of
https://github.com/gorhill/uBlock.git
synced 2024-11-02 00:42:45 +01:00
Fix compilation of blocking counterpart of redirect=
filters
Related issue: - https://github.com/uBlockOrigin/uBlock-issues/issues/1358
This commit is contained in:
parent
7d80416938
commit
57013c16e6
@ -2455,6 +2455,16 @@ const NetOptionsIterator = class {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// `header`: can't be used with any modifier type
|
||||||
|
{
|
||||||
|
const i = this.tokenPos[OPTTokenHeader];
|
||||||
|
if ( i !== -1 && hasBits(allBits, OPTModifierType) ) {
|
||||||
|
optSlices[i] = OPTTokenInvalid;
|
||||||
|
if ( this.interactive ) {
|
||||||
|
this.parser.errorSlices(optSlices[i+1], optSlices[i+5]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
next() {
|
next() {
|
||||||
|
@ -2620,7 +2620,10 @@ const urlTokenizer = new (class {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
const FilterParser = class {
|
const FilterParser = class {
|
||||||
constructor(parser) {
|
constructor(parser, other = undefined) {
|
||||||
|
if ( other !== undefined ) {
|
||||||
|
return Object.assign(this, other);
|
||||||
|
}
|
||||||
this.cantWebsocket = vAPI.cantWebsocket;
|
this.cantWebsocket = vAPI.cantWebsocket;
|
||||||
this.noTokenHash = urlTokenizer.noTokenHash;
|
this.noTokenHash = urlTokenizer.noTokenHash;
|
||||||
this.reIsolateHostname = /^(\*?\.)?([^\x00-\x24\x26-\x2C\x2F\x3A-\x5E\x60\x7B-\x7F]+)(.*)/;
|
this.reIsolateHostname = /^(\*?\.)?([^\x00-\x24\x26-\x2C\x2F\x3A-\x5E\x60\x7B-\x7F]+)(.*)/;
|
||||||
@ -2761,10 +2764,11 @@ const FilterParser = class {
|
|||||||
[ 'new',1412],
|
[ 'new',1412],
|
||||||
]);
|
]);
|
||||||
this.maxTokenLen = urlTokenizer.MAX_TOKEN_LENGTH;
|
this.maxTokenLen = urlTokenizer.MAX_TOKEN_LENGTH;
|
||||||
this.reset();
|
this.reset(parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
reset() {
|
reset(parser) {
|
||||||
|
this.parser = parser;
|
||||||
this.action = BlockAction;
|
this.action = BlockAction;
|
||||||
// anchor: bit vector
|
// anchor: bit vector
|
||||||
// 0000 (0x0): no anchoring
|
// 0000 (0x0): no anchoring
|
||||||
@ -2780,7 +2784,7 @@ const FilterParser = class {
|
|||||||
this.invalid = false;
|
this.invalid = false;
|
||||||
this.pattern = '';
|
this.pattern = '';
|
||||||
this.party = AnyParty;
|
this.party = AnyParty;
|
||||||
this.hasOptionUnits = false;
|
this.optionUnitBits = 0;
|
||||||
this.domainOpt = '';
|
this.domainOpt = '';
|
||||||
this.denyallowOpt = '';
|
this.denyallowOpt = '';
|
||||||
this.headerOpt = undefined;
|
this.headerOpt = undefined;
|
||||||
@ -2800,6 +2804,10 @@ const FilterParser = class {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clone() {
|
||||||
|
return new FilterParser(this.parser, this);
|
||||||
|
}
|
||||||
|
|
||||||
normalizeRegexSource(s) {
|
normalizeRegexSource(s) {
|
||||||
try {
|
try {
|
||||||
const re = new RegExp(s);
|
const re = new RegExp(s);
|
||||||
@ -2830,14 +2838,14 @@ const FilterParser = class {
|
|||||||
this.party |= firstParty ? FirstParty : ThirdParty;
|
this.party |= firstParty ? FirstParty : ThirdParty;
|
||||||
}
|
}
|
||||||
|
|
||||||
parseHostnameList(parser, s, modeBits, out = []) {
|
parseHostnameList(s, modeBits, out = []) {
|
||||||
let beg = 0;
|
let beg = 0;
|
||||||
let slen = s.length;
|
let slen = s.length;
|
||||||
let i = 0;
|
let i = 0;
|
||||||
while ( beg < slen ) {
|
while ( beg < slen ) {
|
||||||
let end = s.indexOf('|', beg);
|
let end = s.indexOf('|', beg);
|
||||||
if ( end === -1 ) { end = slen; }
|
if ( end === -1 ) { end = slen; }
|
||||||
const hn = parser.normalizeHostnameValue(
|
const hn = this.parser.normalizeHostnameValue(
|
||||||
s.slice(beg, end),
|
s.slice(beg, end),
|
||||||
modeBits
|
modeBits
|
||||||
);
|
);
|
||||||
@ -2858,96 +2866,115 @@ const FilterParser = class {
|
|||||||
} else if ( this.action === AllowAction ) {
|
} else if ( this.action === AllowAction ) {
|
||||||
this.modifyValue = '';
|
this.modifyValue = '';
|
||||||
}
|
}
|
||||||
this.hasOptionUnits = true;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
parseOptions(parser) {
|
parseOptions() {
|
||||||
for ( let { id, val, not } of parser.netOptions() ) {
|
for ( let { id, val, not } of this.parser.netOptions() ) {
|
||||||
switch ( id ) {
|
switch ( id ) {
|
||||||
case parser.OPTToken1p:
|
case this.parser.OPTToken1p:
|
||||||
this.parsePartyOption(true, not);
|
this.parsePartyOption(true, not);
|
||||||
break;
|
break;
|
||||||
case parser.OPTToken1pStrict:
|
case this.parser.OPTToken1pStrict:
|
||||||
this.strictParty = this.strictParty === -1 ? 0 : 1;
|
this.strictParty = this.strictParty === -1 ? 0 : 1;
|
||||||
this.hasOptionUnits = true;
|
this.optionUnitBits |= this.STRICT_PARTY_BIT;
|
||||||
break;
|
break;
|
||||||
case parser.OPTToken3p:
|
case this.parser.OPTToken3p:
|
||||||
this.parsePartyOption(false, not);
|
this.parsePartyOption(false, not);
|
||||||
break;
|
break;
|
||||||
case parser.OPTToken3pStrict:
|
case this.parser.OPTToken3pStrict:
|
||||||
this.strictParty = this.strictParty === 1 ? 0 : -1;
|
this.strictParty = this.strictParty === 1 ? 0 : -1;
|
||||||
this.hasOptionUnits = true;
|
this.optionUnitBits |= this.STRICT_PARTY_BIT;
|
||||||
break;
|
break;
|
||||||
case parser.OPTTokenAll:
|
case this.parser.OPTTokenAll:
|
||||||
this.parseTypeOption(-1);
|
this.parseTypeOption(-1);
|
||||||
break;
|
break;
|
||||||
// https://github.com/uBlockOrigin/uAssets/issues/192
|
// https://github.com/uBlockOrigin/uAssets/issues/192
|
||||||
case parser.OPTTokenBadfilter:
|
case this.parser.OPTTokenBadfilter:
|
||||||
this.badFilter = true;
|
this.badFilter = true;
|
||||||
break;
|
break;
|
||||||
case parser.OPTTokenCsp:
|
case this.parser.OPTTokenCsp:
|
||||||
if ( this.parseModifierOption(id, val) === false ) {
|
if ( this.parseModifierOption(id, val) === false ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ( val !== undefined && this.reBadCSP.test(val) ) {
|
if ( val !== undefined && this.reBadCSP.test(val) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
this.optionUnitBits |= this.CSP_BIT;
|
||||||
break;
|
break;
|
||||||
// https://github.com/gorhill/uBlock/issues/2294
|
// https://github.com/gorhill/uBlock/issues/2294
|
||||||
// Detect and discard filter if domain option contains
|
// Detect and discard filter if domain option contains
|
||||||
// nonsensical characters.
|
// nonsensical characters.
|
||||||
case parser.OPTTokenDomain:
|
case this.parser.OPTTokenDomain:
|
||||||
this.domainOpt = this.parseHostnameList(
|
this.domainOpt = this.parseHostnameList(
|
||||||
parser,
|
|
||||||
val,
|
val,
|
||||||
0b1010,
|
0b1010,
|
||||||
this.domainOptList
|
this.domainOptList
|
||||||
);
|
);
|
||||||
if ( this.domainOpt === '' ) { return false; }
|
if ( this.domainOpt === '' ) { return false; }
|
||||||
this.hasOptionUnits = true;
|
this.optionUnitBits |= this.DOMAIN_BIT;
|
||||||
break;
|
break;
|
||||||
case parser.OPTTokenDenyAllow:
|
case this.parser.OPTTokenDenyAllow:
|
||||||
this.denyallowOpt = this.parseHostnameList(parser, val, 0b0000);
|
this.denyallowOpt = this.parseHostnameList(val, 0b0000);
|
||||||
if ( this.denyallowOpt === '' ) { return false; }
|
if ( this.denyallowOpt === '' ) { return false; }
|
||||||
this.hasOptionUnits = true;
|
this.optionUnitBits |= this.DENYALLOW_BIT;
|
||||||
break;
|
break;
|
||||||
// https://www.reddit.com/r/uBlockOrigin/comments/d6vxzj/
|
// https://www.reddit.com/r/uBlockOrigin/comments/d6vxzj/
|
||||||
// Add support for `elemhide`. Rarely used but it happens.
|
// Add support for `elemhide`. Rarely used but it happens.
|
||||||
case parser.OPTTokenEhide:
|
case this.parser.OPTTokenEhide:
|
||||||
this.parseTypeOption(parser.OPTTokenShide, not);
|
this.parseTypeOption(this.parser.OPTTokenShide, not);
|
||||||
this.parseTypeOption(parser.OPTTokenGhide, not);
|
this.parseTypeOption(this.parser.OPTTokenGhide, not);
|
||||||
break;
|
break;
|
||||||
case parser.OPTTokenHeader:
|
case this.parser.OPTTokenHeader:
|
||||||
this.headerOpt = val !== undefined ? val : '';
|
this.headerOpt = val !== undefined ? val : '';
|
||||||
this.hasOptionUnits = true;
|
this.optionUnitBits |= this.HEADER_BIT;
|
||||||
break;
|
break;
|
||||||
case parser.OPTTokenImportant:
|
case this.parser.OPTTokenImportant:
|
||||||
if ( this.action === AllowAction ) { return false; }
|
if ( this.action === AllowAction ) { return false; }
|
||||||
this.action = BlockImportant;
|
this.action = BlockImportant;
|
||||||
break;
|
break;
|
||||||
// Used by Adguard:
|
// Used by Adguard:
|
||||||
// https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#empty-modifier
|
// https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#empty-modifier
|
||||||
case parser.OPTTokenEmpty:
|
case this.parser.OPTTokenEmpty:
|
||||||
if ( this.modifyType !== undefined ) { return false; }
|
id = this.action === AllowAction
|
||||||
this.modifyType = parser.OPTTokenRedirect;
|
? this.parser.OPTTokenRedirectRule
|
||||||
this.modifyValue = 'empty';
|
: this.parser.OPTTokenRedirect;
|
||||||
this.hasOptionUnits = true;
|
if ( this.parseModifierOption(id, 'empty') === false ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.optionUnitBits |= this.REDIRECT_BIT;
|
||||||
break;
|
break;
|
||||||
case parser.OPTTokenMp4:
|
case this.parser.OPTTokenMp4:
|
||||||
if ( this.modifyType !== undefined ) { return false; }
|
id = this.action === AllowAction
|
||||||
this.modifyType = parser.OPTTokenRedirect;
|
? this.parser.OPTTokenRedirectRule
|
||||||
this.modifyValue = 'noopmp4-1s';
|
: this.parser.OPTTokenRedirect;
|
||||||
this.hasOptionUnits = true;
|
if ( this.parseModifierOption(id, 'noopmp4-1s') === false ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.optionUnitBits |= this.REDIRECT_BIT;
|
||||||
break;
|
break;
|
||||||
case parser.OPTTokenQueryprune:
|
case this.parser.OPTTokenQueryprune:
|
||||||
case parser.OPTTokenRedirect:
|
|
||||||
case parser.OPTTokenRedirectRule:
|
|
||||||
if ( this.parseModifierOption(id, val) === false ) {
|
if ( this.parseModifierOption(id, val) === false ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
this.optionUnitBits |= this.QUERYPRUNE_BIT;
|
||||||
break;
|
break;
|
||||||
case parser.OPTTokenInvalid:
|
case this.parser.OPTTokenRedirect:
|
||||||
|
if ( this.action === AllowAction ) {
|
||||||
|
id = this.parser.OPTTokenRedirectRule;
|
||||||
|
}
|
||||||
|
if ( this.parseModifierOption(id, val) === false ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.optionUnitBits |= this.REDIRECT_BIT;
|
||||||
|
break;
|
||||||
|
case this.parser.OPTTokenRedirectRule:
|
||||||
|
if ( this.parseModifierOption(id, val) === false ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.optionUnitBits |= this.REDIRECT_BIT;
|
||||||
|
break;
|
||||||
|
case this.parser.OPTTokenInvalid:
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
if ( this.tokenIdToNormalizedType.has(id) === false ) {
|
if ( this.tokenIdToNormalizedType.has(id) === false ) {
|
||||||
@ -2971,10 +2998,10 @@ const FilterParser = class {
|
|||||||
if ( this.typeBits === 0 ) { return false; }
|
if ( this.typeBits === 0 ) { return false; }
|
||||||
}
|
}
|
||||||
// CSP directives implicitly apply only to document/subdocument.
|
// CSP directives implicitly apply only to document/subdocument.
|
||||||
if ( this.modifyType === parser.OPTTokenCsp ) {
|
if ( this.modifyType === this.parser.OPTTokenCsp ) {
|
||||||
if ( this.typeBits === 0 ) {
|
if ( this.typeBits === 0 ) {
|
||||||
this.parseTypeOption(parser.OPTTokenDoc, false);
|
this.parseTypeOption(this.parser.OPTTokenDoc, false);
|
||||||
this.parseTypeOption(parser.OPTTokenFrame, false);
|
this.parseTypeOption(this.parser.OPTTokenFrame, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// https://github.com/gorhill/uBlock/issues/2283
|
// https://github.com/gorhill/uBlock/issues/2283
|
||||||
@ -2989,7 +3016,7 @@ const FilterParser = class {
|
|||||||
|
|
||||||
parse(parser) {
|
parse(parser) {
|
||||||
// important!
|
// important!
|
||||||
this.reset();
|
this.reset(parser);
|
||||||
|
|
||||||
if ( parser.hasError() ) {
|
if ( parser.hasError() ) {
|
||||||
this.invalid = true;
|
this.invalid = true;
|
||||||
@ -3019,7 +3046,7 @@ const FilterParser = class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// options
|
// options
|
||||||
if ( parser.hasOptions() && this.parseOptions(parser) === false ) {
|
if ( parser.hasOptions() && this.parseOptions() === false ) {
|
||||||
this.unsupported = true;
|
this.unsupported = true;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -3084,11 +3111,12 @@ const FilterParser = class {
|
|||||||
// are not good. Avoid if possible. This has a significant positive
|
// are not good. Avoid if possible. This has a significant positive
|
||||||
// impact on performance.
|
// impact on performance.
|
||||||
|
|
||||||
makeToken(parser) {
|
makeToken() {
|
||||||
|
if ( this.pattern === '*' ) { return; }
|
||||||
if ( this.isRegex ) {
|
if ( this.isRegex ) {
|
||||||
return this.extractTokenFromRegex();
|
return this.extractTokenFromRegex();
|
||||||
}
|
}
|
||||||
const match = this.extractTokenFromPattern(parser);
|
const match = this.extractTokenFromPattern();
|
||||||
if ( match === null ) { return; }
|
if ( match === null ) { return; }
|
||||||
this.token = match.token;
|
this.token = match.token;
|
||||||
this.tokenHash = urlTokenizer.tokenHashFromString(this.token);
|
this.tokenHash = urlTokenizer.tokenHashFromString(this.token);
|
||||||
@ -3096,10 +3124,10 @@ const FilterParser = class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Note: a one-char token is better than a documented bad token.
|
// Note: a one-char token is better than a documented bad token.
|
||||||
extractTokenFromPattern(parser) {
|
extractTokenFromPattern() {
|
||||||
let bestMatch = null;
|
let bestMatch = null;
|
||||||
let bestBadness = 0x7FFFFFFF;
|
let bestBadness = 0x7FFFFFFF;
|
||||||
for ( const match of parser.patternTokens() ) {
|
for ( const match of this.parser.patternTokens() ) {
|
||||||
const badness = match.token.length > 1
|
const badness = match.token.length > 1
|
||||||
? this.badTokens.get(match.token) || 0
|
? this.badTokens.get(match.token) || 0
|
||||||
: 1;
|
: 1;
|
||||||
@ -3162,18 +3190,13 @@ const FilterParser = class {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isJustPattern() {
|
hasNoOptionUnits() {
|
||||||
return this.hasOptionUnits === false;
|
return this.optionUnitBits === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
isJustOrigin() {
|
isJustOrigin() {
|
||||||
return this.hasOptionUnits &&
|
return this.optionUnitBits === this.DOMAIN_BIT &&
|
||||||
this.isRegex === false &&
|
this.isRegex === false && (
|
||||||
this.modifyType === undefined &&
|
|
||||||
this.strictParty === 0 &&
|
|
||||||
this.headerOpt === undefined &&
|
|
||||||
this.denyallowOpt === '' &&
|
|
||||||
this.domainOpt !== '' && (
|
|
||||||
this.pattern === '*' || (
|
this.pattern === '*' || (
|
||||||
this.anchor === 0b010 &&
|
this.anchor === 0b010 &&
|
||||||
/^(?:http[s*]?:(?:\/\/)?)$/.test(this.pattern)
|
/^(?:http[s*]?:(?:\/\/)?)$/.test(this.pattern)
|
||||||
@ -3190,6 +3213,15 @@ const FilterParser = class {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FilterParser.prototype.DOMAIN_BIT = 0b00000001;
|
||||||
|
FilterParser.prototype.DENYALLOW_BIT = 0b00000010;
|
||||||
|
FilterParser.prototype.HEADER_BIT = 0b00000100;
|
||||||
|
FilterParser.prototype.STRICT_PARTY_BIT = 0b00001000;
|
||||||
|
|
||||||
|
FilterParser.prototype.CSP_BIT = 0b00010000;
|
||||||
|
FilterParser.prototype.QUERYPRUNE_BIT = 0b00100000;
|
||||||
|
FilterParser.prototype.REDIRECT_BIT = 0b01000000;
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
FilterParser.parse = (( ) => {
|
FilterParser.parse = (( ) => {
|
||||||
@ -3558,19 +3590,38 @@ FilterContainer.prototype.compile = function(parser, writer) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pure hostnames, use more efficient dictionary lookup
|
// 0 = network filters
|
||||||
// https://github.com/chrisaljoudi/uBlock/issues/665
|
// 1 = network filters: bad filters
|
||||||
// Create a dict keyed on request type etc.
|
writer.select(parsed.badFilter ? 1 : 0);
|
||||||
if ( parsed.isPureHostname && parsed.isJustPattern() ) {
|
|
||||||
parsed.tokenHash = this.dotTokenHash;
|
// Reminder:
|
||||||
this.compileToAtomicFilter(parsed, parsed.pattern, writer);
|
// `redirect=` is a combination of a `redirect-rule` filter and a
|
||||||
return true;
|
// block filter.
|
||||||
|
if ( parsed.modifyType === parser.OPTTokenRedirect ) {
|
||||||
|
parsed.modifyType = parser.OPTTokenRedirectRule;
|
||||||
|
const parsedBlock = parsed.clone();
|
||||||
|
parsedBlock.modifyType = undefined;
|
||||||
|
parsedBlock.optionUnitBits &= ~parsed.REDIRECT_BIT;
|
||||||
|
this.compileParsed(parsedBlock, writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( parser.patternIsMatchAll() === false ) {
|
this.compileParsed(parsed, writer);
|
||||||
parsed.makeToken(parser);
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
FilterContainer.prototype.compileParsed = function(parsed, writer) {
|
||||||
|
// Pure hostnames, use more efficient dictionary lookup
|
||||||
|
if ( parsed.isPureHostname && parsed.hasNoOptionUnits() ) {
|
||||||
|
parsed.tokenHash = this.dotTokenHash;
|
||||||
|
this.compileToAtomicFilter(parsed, parsed.pattern, writer);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parsed.makeToken();
|
||||||
|
|
||||||
// Special pattern/option cases:
|
// Special pattern/option cases:
|
||||||
// - `*$domain=...`
|
// - `*$domain=...`
|
||||||
// - `|http://$domain=...`
|
// - `|http://$domain=...`
|
||||||
@ -3595,7 +3646,7 @@ FilterContainer.prototype.compile = function(parser, writer) {
|
|||||||
entities.push(hn);
|
entities.push(hn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( entities.length === 0 ) { return true; }
|
if ( entities.length === 0 ) { return; }
|
||||||
parsed.tokenHash = tokenHash;
|
parsed.tokenHash = tokenHash;
|
||||||
const leftAnchored = (parsed.anchor & 0b010) !== 0;
|
const leftAnchored = (parsed.anchor & 0b010) !== 0;
|
||||||
for ( const entity of entities ) {
|
for ( const entity of entities ) {
|
||||||
@ -3607,7 +3658,7 @@ FilterContainer.prototype.compile = function(parser, writer) {
|
|||||||
parsed, FilterCompositeAll.compile(units), writer
|
parsed, FilterCompositeAll.compile(units), writer
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const units = [];
|
const units = [];
|
||||||
@ -3656,30 +3707,16 @@ FilterContainer.prototype.compile = function(parser, writer) {
|
|||||||
|
|
||||||
// Modifier
|
// Modifier
|
||||||
//
|
//
|
||||||
// IMPORTANT: the modifier unit MUST always appear first in a sequence.
|
// IMPORTANT: the modifier unit MUST always appear first in a sequence
|
||||||
//
|
|
||||||
// Reminder: A block filter is implicit with `redirect=` modifier.
|
|
||||||
if ( parsed.modifyType !== undefined ) {
|
if ( parsed.modifyType !== undefined ) {
|
||||||
if (
|
|
||||||
parsed.modifyType === parser.OPTTokenRedirect &&
|
|
||||||
parsed.action !== AllowAction
|
|
||||||
) {
|
|
||||||
const fdata = units.length === 1
|
|
||||||
? units[0]
|
|
||||||
: FilterCompositeAll.compile(units);
|
|
||||||
this.compileToAtomicFilter(parsed, fdata, writer);
|
|
||||||
parsed.modifyType = parser.OPTTokenRedirectRule;
|
|
||||||
}
|
|
||||||
units.unshift(FilterModifier.compile(parsed));
|
units.unshift(FilterModifier.compile(parsed));
|
||||||
parsed.action = ModifyAction;
|
parsed.action = (parsed.action & ~ActionBitsMask) | ModifyAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fdata = units.length === 1
|
const fdata = units.length === 1
|
||||||
? units[0]
|
? units[0]
|
||||||
: FilterCompositeAll.compile(units);
|
: FilterCompositeAll.compile(units);
|
||||||
this.compileToAtomicFilter(parsed, fdata, writer);
|
this.compileToAtomicFilter(parsed, fdata, writer);
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -3689,10 +3726,6 @@ FilterContainer.prototype.compileToAtomicFilter = function(
|
|||||||
fdata,
|
fdata,
|
||||||
writer
|
writer
|
||||||
) {
|
) {
|
||||||
// 0 = network filters
|
|
||||||
// 1 = network filters: bad filters
|
|
||||||
writer.select(parsed.badFilter ? 1 : 0);
|
|
||||||
|
|
||||||
const catBits = parsed.action | parsed.party;
|
const catBits = parsed.action | parsed.party;
|
||||||
let typeBits = parsed.typeBits;
|
let typeBits = parsed.typeBits;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user