Add support for network filter option message

Related issue:
https://github.com/uBlockOrigin/uBlock-issues/issues/1195
This commit is contained in:
Raymond Hill 2025-05-29 13:23:56 -04:00
parent eb3f5a44a9
commit d8298bb067
No known key found for this signature in database
GPG key ID: 25E1490B761470C2
2 changed files with 60 additions and 10 deletions

View file

@ -174,6 +174,7 @@ export const NODE_TYPE_NET_OPTION_NAME_INLINESCRIPT = iota++;
export const NODE_TYPE_NET_OPTION_NAME_IPADDRESS = iota++;
export const NODE_TYPE_NET_OPTION_NAME_MATCHCASE = iota++;
export const NODE_TYPE_NET_OPTION_NAME_MEDIA = iota++;
export const NODE_TYPE_NET_OPTION_NAME_MESSAGE = iota++;
export const NODE_TYPE_NET_OPTION_NAME_METHOD = iota++;
export const NODE_TYPE_NET_OPTION_NAME_MP4 = iota++;
export const NODE_TYPE_NET_OPTION_NAME_NOOP = iota++;
@ -255,6 +256,7 @@ export const nodeTypeFromOptionName = new Map([
[ 'ipaddress', NODE_TYPE_NET_OPTION_NAME_IPADDRESS ],
[ 'match-case', NODE_TYPE_NET_OPTION_NAME_MATCHCASE ],
[ 'media', NODE_TYPE_NET_OPTION_NAME_MEDIA ],
[ 'message', NODE_TYPE_NET_OPTION_NAME_MESSAGE ],
[ 'method', NODE_TYPE_NET_OPTION_NAME_METHOD ],
[ 'mp4', NODE_TYPE_NET_OPTION_NAME_MP4 ],
[ '_', NODE_TYPE_NET_OPTION_NAME_NOOP ],
@ -1350,6 +1352,9 @@ export class AstFilterParser {
case NODE_TYPE_NET_OPTION_NAME_MATCHCASE:
realBad = this.isRegexPattern() === false;
break;
case NODE_TYPE_NET_OPTION_NAME_MESSAGE:
realBad = hasValue === false;
break;
case NODE_TYPE_NET_OPTION_NAME_PERMISSIONS:
realBad = modifierType !== 0 ||
(hasValue || isException) === false ||
@ -3149,6 +3154,7 @@ export const netOptionTokenDescriptors = new Map([
[ 'ipaddress', { mustAssign: true } ],
[ 'match-case', { } ],
[ 'media', { canNegate: true } ],
[ 'message', { mustAssign: true } ],
[ 'method', { mustAssign: true } ],
[ 'mp4', { blockOnly: true } ],
[ '_', { } ],

View file

@ -3103,6 +3103,39 @@ class FilterIPAddress {
registerFilterClass(FilterIPAddress);
/******************************************************************************/
class FilterMessage {
static match() {
return true;
}
static compile(details) {
return [
FilterMessage.fid,
encodeURIComponent(details.optionValues.get('message')),
];
}
static fromCompiled(args) {
const msg = args[1];
return filterDataAlloc(args[0], bidiTrie.storeString(msg), msg.length);
}
static keyFromArgs() {
}
static logData(idata, details) {
const msg = bidiTrie.extractString(
filterData[idata+1],
filterData[idata+2]
);
details.options.push(`message=${decodeURIComponent(msg)}`);
}
}
registerFilterClass(FilterMessage);
/******************************************************************************/
/******************************************************************************/
@ -3578,6 +3611,10 @@ class FilterCompiler {
this.optionValues.set('ipaddress', parser.getNetOptionValue(id) || '');
this.optionUnitBits |= IPADDRESS_BIT;
break;
case sfp.NODE_TYPE_NET_OPTION_NAME_MESSAGE:
this.optionValues.set('message', parser.getNetOptionValue(id));
this.optionUnitBits |= MESSAGE_BIT;
break;
case sfp.NODE_TYPE_NET_OPTION_NAME_METHOD:
this.processMethodOption(parser.getNetOptionValue(id));
this.optionUnitBits |= METHOD_BIT;
@ -3699,6 +3736,7 @@ class FilterCompiler {
case sfp.NODE_TYPE_NET_OPTION_NAME_FROM:
case sfp.NODE_TYPE_NET_OPTION_NAME_HEADER:
case sfp.NODE_TYPE_NET_OPTION_NAME_IPADDRESS:
case sfp.NODE_TYPE_NET_OPTION_NAME_MESSAGE:
case sfp.NODE_TYPE_NET_OPTION_NAME_METHOD:
case sfp.NODE_TYPE_NET_OPTION_NAME_PERMISSIONS:
case sfp.NODE_TYPE_NET_OPTION_NAME_REDIRECT:
@ -4081,6 +4119,11 @@ class FilterCompiler {
this.action |= HEADERS_REALM;
}
// Message
if ( (this.optionUnitBits & MESSAGE_BIT) !== 0 ) {
units.push(FilterMessage.compile(this));
}
// Important
//
// IMPORTANT: must always appear at the end of the sequence, so as to
@ -4175,16 +4218,17 @@ class FilterCompiler {
}
// These are to quickly test whether a filter is composite
const FROM_BIT = 0b0000000001;
const TO_BIT = 0b0000000010;
const DENYALLOW_BIT = 0b0000000100;
const HEADER_BIT = 0b0000001000;
const STRICT_PARTY_BIT = 0b0000010000;
const MODIFY_BIT = 0b0000100000;
const NOT_TYPE_BIT = 0b0001000000;
const IMPORTANT_BIT = 0b0010000000;
const METHOD_BIT = 0b0100000000;
const IPADDRESS_BIT = 0b1000000000;
const FROM_BIT = 0b00000000001;
const TO_BIT = 0b00000000010;
const DENYALLOW_BIT = 0b00000000100;
const HEADER_BIT = 0b00000001000;
const STRICT_PARTY_BIT = 0b00000010000;
const MODIFY_BIT = 0b00000100000;
const NOT_TYPE_BIT = 0b00001000000;
const IMPORTANT_BIT = 0b00010000000;
const METHOD_BIT = 0b00100000000;
const IPADDRESS_BIT = 0b01000000000;
const MESSAGE_BIT = 0b10000000000
FilterCompiler.prototype.FILTER_OK = 0;
FilterCompiler.prototype.FILTER_INVALID = 1;