1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-11-16 23:42:39 +01:00

Compare commits

..

No commits in common. "aaceabeba1b54d07c5ec7045193821a3f4bd5b8e" and "7be7e0b8709d87f3e32fbf49063ed04ea05dc4c3" have entirely different histories.

5 changed files with 258 additions and 281 deletions

View File

@ -1,4 +1,3 @@
- [Add `:matches-prop()` pseudo CSS operator](https://github.com/gorhill/uBlock/commit/aca7674bac)
- [Improve `set-cookie` scriptlet](https://github.com/gorhill/uBlock/commit/b4d8750f44) - [Improve `set-cookie` scriptlet](https://github.com/gorhill/uBlock/commit/b4d8750f44)
- [Improve `trusted-replace-node-text` scriptlet](https://github.com/gorhill/uBlock/commit/cb0f65e035) - [Improve `trusted-replace-node-text` scriptlet](https://github.com/gorhill/uBlock/commit/cb0f65e035)
- [Improve `trusted-replace-[fetch|xhr]-response` scriptlets](https://github.com/gorhill/uBlock/commit/9072772f61) - [Improve `trusted-replace-[fetch|xhr]-response` scriptlets](https://github.com/gorhill/uBlock/commit/9072772f61)

View File

@ -3,9 +3,9 @@
"uBlock0@raymondhill.net": { "uBlock0@raymondhill.net": {
"updates": [ "updates": [
{ {
"version": "1.58.1.9", "version": "1.58.1.8",
"browser_specific_settings": { "gecko": { "strict_min_version": "78.0" } }, "browser_specific_settings": { "gecko": { "strict_min_version": "78.0" } },
"update_link": "https://github.com/gorhill/uBlock/releases/download/1.58.1b9/uBlock0_1.58.1b9.firefox.signed.xpi" "update_link": "https://github.com/gorhill/uBlock/releases/download/1.58.1b8/uBlock0_1.58.1b8.firefox.signed.xpi"
} }
] ]
} }

2
dist/version vendored
View File

@ -1 +1 @@
1.58.1.9 1.58.1.8

View File

@ -173,26 +173,6 @@ class PSelectorMatchesPathTask extends PSelectorTask {
} }
} }
class PSelectorMatchesPropTask extends PSelectorTask {
constructor(task) {
super();
this.props = task[1].attr.split('.');
this.reValue = task[1].value !== ''
? regexFromString(task[1].value, true)
: null;
}
transpose(node, output) {
let value = node;
for ( const prop of this.props ) {
if ( value === undefined ) { return; }
if ( value === null ) { return; }
value = value[prop];
}
if ( this.reValue !== null && this.reValue.test(value) === false ) { return; }
output.push(node);
}
}
class PSelectorMinTextLengthTask extends PSelectorTask { class PSelectorMinTextLengthTask extends PSelectorTask {
constructor(task) { constructor(task) {
super(); super();
@ -481,7 +461,6 @@ PSelector.prototype.operatorToTaskMap = new Map([
[ 'matches-css-before', PSelectorMatchesCSSBeforeTask ], [ 'matches-css-before', PSelectorMatchesCSSBeforeTask ],
[ 'matches-media', PSelectorMatchesMediaTask ], [ 'matches-media', PSelectorMatchesMediaTask ],
[ 'matches-path', PSelectorMatchesPathTask ], [ 'matches-path', PSelectorMatchesPathTask ],
[ 'matches-prop', PSelectorMatchesPropTask ],
[ 'min-text-length', PSelectorMinTextLengthTask ], [ 'min-text-length', PSelectorMinTextLengthTask ],
[ 'not', PSelectorIfNotTask ], [ 'not', PSelectorIfNotTask ],
[ 'others', PSelectorOthersTask ], [ 'others', PSelectorOthersTask ],

View File

@ -19,10 +19,12 @@
Home: https://github.com/gorhill/uBlock Home: https://github.com/gorhill/uBlock
*/ */
'use strict';
/******************************************************************************/ /******************************************************************************/
import * as cssTree from '../lib/csstree/css-tree.js';
import Regex from '../lib/regexanalyzer/regex.js'; import Regex from '../lib/regexanalyzer/regex.js';
import * as cssTree from '../lib/csstree/css-tree.js';
/******************************************************************************* /*******************************************************************************
* *
@ -779,21 +781,21 @@ class DomainListIterator {
let ready = false; let ready = false;
while ( node !== 0 ) { while ( node !== 0 ) {
switch ( this.parser.getNodeType(node) ) { switch ( this.parser.getNodeType(node) ) {
case NODE_TYPE_OPTION_VALUE_DOMAIN_RAW: case NODE_TYPE_OPTION_VALUE_DOMAIN_RAW:
this.item.hn = ''; this.item.hn = '';
this.item.not = false; this.item.not = false;
this.item.bad = this.parser.getNodeFlags(node, NODE_FLAG_ERROR) !== 0; this.item.bad = this.parser.getNodeFlags(node, NODE_FLAG_ERROR) !== 0;
break; break;
case NODE_TYPE_OPTION_VALUE_NOT: case NODE_TYPE_OPTION_VALUE_NOT:
this.item.not = true; this.item.not = true;
break; break;
case NODE_TYPE_OPTION_VALUE_DOMAIN: case NODE_TYPE_OPTION_VALUE_DOMAIN:
this.item.hn = this.parser.getNodeTransform(node); this.item.hn = this.parser.getNodeTransform(node);
this.value = this.item; this.value = this.item;
ready = true; ready = true;
break; break;
default: default:
break; break;
} }
node = this.walker.next(); node = this.walker.next();
if ( ready ) { return this; } if ( ready ) { return this; }
@ -857,17 +859,17 @@ export class AstFilterParser {
this.reInlineComment = /(?:\s+#).*?$/; this.reInlineComment = /(?:\s+#).*?$/;
this.reNetException = /^@@/; this.reNetException = /^@@/;
this.reNetAnchor = /(?:)\$[^,\w~]/; this.reNetAnchor = /(?:)\$[^,\w~]/;
this.reHnAnchoredPlainAscii = /^\|\|[0-9a-z%&,\-./:;=?_]+$/; this.reHnAnchoredPlainAscii = /^\|\|[0-9a-z%&,\-.\/:;=?_]+$/;
this.reHnAnchoredHostnameAscii = /^\|\|(?:[\da-z][\da-z_-]*\.)*[\da-z_-]*[\da-z]\^$/; this.reHnAnchoredHostnameAscii = /^\|\|(?:[\da-z][\da-z_-]*\.)*[\da-z_-]*[\da-z]\^$/;
this.reHnAnchoredHostnameUnicode = /^\|\|(?:[\p{L}\p{N}][\p{L}\p{N}\u{2d}]*\.)*[\p{L}\p{N}\u{2d}]*[\p{L}\p{N}]\^$/u; this.reHnAnchoredHostnameUnicode = /^\|\|(?:[\p{L}\p{N}][\p{L}\p{N}\u{2d}]*\.)*[\p{L}\p{N}\u{2d}]*[\p{L}\p{N}]\^$/u;
this.reHn3pAnchoredHostnameAscii = /^\|\|(?:[\da-z][\da-z_-]*\.)*[\da-z_-]*[\da-z]\^\$third-party$/; this.reHn3pAnchoredHostnameAscii = /^\|\|(?:[\da-z][\da-z_-]*\.)*[\da-z_-]*[\da-z]\^\$third-party$/;
this.rePlainAscii = /^[0-9a-z%&\-./:;=?_]{2,}$/; this.rePlainAscii = /^[0-9a-z%&\-.\/:;=?_]{2,}$/;
this.reNetHosts1 = /^127\.0\.0\.1 (?:[\da-z][\da-z_-]*\.)+[\da-z-]*[a-z]$/; this.reNetHosts1 = /^127\.0\.0\.1 (?:[\da-z][\da-z_-]*\.)+[\da-z-]*[a-z]$/;
this.reNetHosts2 = /^0\.0\.0\.0 (?:[\da-z][\da-z_-]*\.)+[\da-z-]*[a-z]$/; this.reNetHosts2 = /^0\.0\.0\.0 (?:[\da-z][\da-z_-]*\.)+[\da-z-]*[a-z]$/;
this.rePlainGenericCosmetic = /^##[.#][A-Za-z_][\w-]*$/; this.rePlainGenericCosmetic = /^##[.#][A-Za-z_][\w-]*$/;
this.reHostnameAscii = /^(?:[\da-z][\da-z_-]*\.)*[\da-z][\da-z-]*[\da-z]$/; this.reHostnameAscii = /^(?:[\da-z][\da-z_-]*\.)*[\da-z][\da-z-]*[\da-z]$/;
this.rePlainEntity = /^(?:[\da-z][\da-z_-]*\.)+\*$/; this.rePlainEntity = /^(?:[\da-z][\da-z_-]*\.)+\*$/;
this.reHostsSink = /^[\w%.:[\]-]+\s+/; this.reHostsSink = /^[\w%.:\[\]-]+\s+/;
this.reHostsRedirect = /(?:0\.0\.0\.0|broadcasthost|local|localhost(?:\.localdomain)?|ip6-\w+)(?:[^\w.-]|$)/; this.reHostsRedirect = /(?:0\.0\.0\.0|broadcasthost|local|localhost(?:\.localdomain)?|ip6-\w+)(?:[^\w.-]|$)/;
this.reNetOptionComma = /,(?:~?[13a-z-]+(?:=.*?)?|_+)(?:,|$)/; this.reNetOptionComma = /,(?:~?[13a-z-]+(?:=.*?)?|_+)(?:,|$)/;
this.rePointlessLeftAnchor = /^\|\|?\*+/; this.rePointlessLeftAnchor = /^\|\|?\*+/;
@ -884,8 +886,8 @@ export class AstFilterParser {
this.rePreparseDirectiveIf = /^!#if /; this.rePreparseDirectiveIf = /^!#if /;
this.rePreparseDirectiveAny = /^!#(?:else|endif|if |include )/; this.rePreparseDirectiveAny = /^!#(?:else|endif|if |include )/;
this.reURL = /\bhttps?:\/\/\S+/; this.reURL = /\bhttps?:\/\/\S+/;
this.reHasPatternSpecialChars = /[*^]/; this.reHasPatternSpecialChars = /[\*\^]/;
this.rePatternAllSpecialChars = /[*^]+|[^\x00-\x7f]+/g; this.rePatternAllSpecialChars = /[\*\^]+|[^\x00-\x7f]+/g;
// https://github.com/uBlockOrigin/uBlock-issues/issues/1146 // https://github.com/uBlockOrigin/uBlock-issues/issues/1146
// From https://codemirror.net/doc/manual.html#option_specialChars // From https://codemirror.net/doc/manual.html#option_specialChars
this.reHasInvalidChar = /[\x00-\x1F\x7F-\x9F\xAD\u061C\u200B-\u200F\u2028\u2029\uFEFF\uFFF9-\uFFFC]/; this.reHasInvalidChar = /[\x00-\x1F\x7F-\x9F\xAD\u061C\u200B-\u200F\u2028\u2029\uFEFF\uFFF9-\uFFFC]/;
@ -1313,148 +1315,148 @@ export class AstFilterParser {
const hasValue = (flags & NODE_FLAG_OPTION_HAS_VALUE) !== 0; const hasValue = (flags & NODE_FLAG_OPTION_HAS_VALUE) !== 0;
bad = false; realBad = false; bad = false; realBad = false;
switch ( type ) { switch ( type ) {
case NODE_TYPE_NET_OPTION_NAME_ALL: case NODE_TYPE_NET_OPTION_NAME_ALL:
realBad = isNegated || hasValue || modifierType !== 0; realBad = isNegated || hasValue || modifierType !== 0;
break; break;
case NODE_TYPE_NET_OPTION_NAME_1P: case NODE_TYPE_NET_OPTION_NAME_1P:
case NODE_TYPE_NET_OPTION_NAME_3P: case NODE_TYPE_NET_OPTION_NAME_3P:
realBad = hasValue; realBad = hasValue;
break; break;
case NODE_TYPE_NET_OPTION_NAME_BADFILTER: case NODE_TYPE_NET_OPTION_NAME_BADFILTER:
badfilter = true; badfilter = true;
/* falls through */ /* falls through */
case NODE_TYPE_NET_OPTION_NAME_NOOP: case NODE_TYPE_NET_OPTION_NAME_NOOP:
realBad = isNegated || hasValue; realBad = isNegated || hasValue;
break; break;
case NODE_TYPE_NET_OPTION_NAME_CSS: case NODE_TYPE_NET_OPTION_NAME_CSS:
case NODE_TYPE_NET_OPTION_NAME_FONT: case NODE_TYPE_NET_OPTION_NAME_FONT:
case NODE_TYPE_NET_OPTION_NAME_IMAGE: case NODE_TYPE_NET_OPTION_NAME_IMAGE:
case NODE_TYPE_NET_OPTION_NAME_MEDIA: case NODE_TYPE_NET_OPTION_NAME_MEDIA:
case NODE_TYPE_NET_OPTION_NAME_OBJECT: case NODE_TYPE_NET_OPTION_NAME_OBJECT:
case NODE_TYPE_NET_OPTION_NAME_OTHER: case NODE_TYPE_NET_OPTION_NAME_OTHER:
case NODE_TYPE_NET_OPTION_NAME_SCRIPT: case NODE_TYPE_NET_OPTION_NAME_SCRIPT:
case NODE_TYPE_NET_OPTION_NAME_XHR: case NODE_TYPE_NET_OPTION_NAME_XHR:
realBad = hasValue; realBad = hasValue;
if ( realBad ) { break; } if ( realBad ) { break; }
requestTypeCount += 1; requestTypeCount += 1;
break; break;
case NODE_TYPE_NET_OPTION_NAME_CNAME: case NODE_TYPE_NET_OPTION_NAME_CNAME:
realBad = isException === false || isNegated || hasValue; realBad = isException === false || isNegated || hasValue;
if ( realBad ) { break; } if ( realBad ) { break; }
modifierType = type; modifierType = type;
break; break;
case NODE_TYPE_NET_OPTION_NAME_CSP: case NODE_TYPE_NET_OPTION_NAME_CSP:
realBad = (hasValue || isException) === false || realBad = (hasValue || isException) === false ||
modifierType !== 0 || modifierType !== 0 ||
this.reBadCSP.test( this.reBadCSP.test(
this.getNetOptionValue(NODE_TYPE_NET_OPTION_NAME_CSP) this.getNetOptionValue(NODE_TYPE_NET_OPTION_NAME_CSP)
); );
if ( realBad ) { break; } if ( realBad ) { break; }
modifierType = type; modifierType = type;
break; break;
case NODE_TYPE_NET_OPTION_NAME_DENYALLOW: case NODE_TYPE_NET_OPTION_NAME_DENYALLOW:
realBad = isNegated || hasValue === false || realBad = isNegated || hasValue === false ||
this.getBranchFromType(NODE_TYPE_NET_OPTION_NAME_FROM) === 0; this.getBranchFromType(NODE_TYPE_NET_OPTION_NAME_FROM) === 0;
break; break;
case NODE_TYPE_NET_OPTION_NAME_DOC: case NODE_TYPE_NET_OPTION_NAME_DOC:
case NODE_TYPE_NET_OPTION_NAME_FRAME: case NODE_TYPE_NET_OPTION_NAME_FRAME:
realBad = hasValue; realBad = hasValue;
if ( realBad ) { break; } if ( realBad ) { break; }
docTypeCount += 1; docTypeCount += 1;
break; break;
case NODE_TYPE_NET_OPTION_NAME_EHIDE: case NODE_TYPE_NET_OPTION_NAME_EHIDE:
case NODE_TYPE_NET_OPTION_NAME_GHIDE: case NODE_TYPE_NET_OPTION_NAME_GHIDE:
case NODE_TYPE_NET_OPTION_NAME_SHIDE: case NODE_TYPE_NET_OPTION_NAME_SHIDE:
realBad = isNegated || hasValue || modifierType !== 0; realBad = isNegated || hasValue || modifierType !== 0;
if ( realBad ) { break; } if ( realBad ) { break; }
behaviorTypeCount += 1; behaviorTypeCount += 1;
unredirectableTypeCount += 1; unredirectableTypeCount += 1;
break; break;
case NODE_TYPE_NET_OPTION_NAME_EMPTY: case NODE_TYPE_NET_OPTION_NAME_EMPTY:
case NODE_TYPE_NET_OPTION_NAME_MP4: case NODE_TYPE_NET_OPTION_NAME_MP4:
realBad = isNegated || hasValue || modifierType !== 0; realBad = isNegated || hasValue || modifierType !== 0;
if ( realBad ) { break; } if ( realBad ) { break; }
modifierType = type; modifierType = type;
break; break;
case NODE_TYPE_NET_OPTION_NAME_FROM: case NODE_TYPE_NET_OPTION_NAME_FROM:
case NODE_TYPE_NET_OPTION_NAME_METHOD: case NODE_TYPE_NET_OPTION_NAME_METHOD:
case NODE_TYPE_NET_OPTION_NAME_TO: case NODE_TYPE_NET_OPTION_NAME_TO:
realBad = isNegated || hasValue === false; realBad = isNegated || hasValue === false;
break; break;
case NODE_TYPE_NET_OPTION_NAME_GENERICBLOCK: case NODE_TYPE_NET_OPTION_NAME_GENERICBLOCK:
bad = true; bad = true;
realBad = isException === false || isNegated || hasValue; realBad = isException === false || isNegated || hasValue;
break; break;
case NODE_TYPE_NET_OPTION_NAME_HEADER: case NODE_TYPE_NET_OPTION_NAME_HEADER:
realBad = isNegated || hasValue === false; realBad = isNegated || hasValue === false;
break; break;
case NODE_TYPE_NET_OPTION_NAME_IMPORTANT: case NODE_TYPE_NET_OPTION_NAME_IMPORTANT:
realBad = isException || isNegated || hasValue; realBad = isException || isNegated || hasValue;
break; break;
case NODE_TYPE_NET_OPTION_NAME_INLINEFONT: case NODE_TYPE_NET_OPTION_NAME_INLINEFONT:
case NODE_TYPE_NET_OPTION_NAME_INLINESCRIPT: case NODE_TYPE_NET_OPTION_NAME_INLINESCRIPT:
realBad = hasValue; realBad = hasValue;
if ( realBad ) { break; } if ( realBad ) { break; }
modifierType = type; modifierType = type;
unredirectableTypeCount += 1; unredirectableTypeCount += 1;
break; break;
case NODE_TYPE_NET_OPTION_NAME_MATCHCASE: case NODE_TYPE_NET_OPTION_NAME_MATCHCASE:
realBad = this.isRegexPattern() === false; realBad = this.isRegexPattern() === false;
break; break;
case NODE_TYPE_NET_OPTION_NAME_PERMISSIONS: case NODE_TYPE_NET_OPTION_NAME_PERMISSIONS:
realBad = modifierType !== 0 || realBad = modifierType !== 0 ||
(hasValue || isException) === false || (hasValue || isException) === false ||
this.reBadPP.test( this.reBadPP.test(
this.getNetOptionValue(NODE_TYPE_NET_OPTION_NAME_PERMISSIONS) this.getNetOptionValue(NODE_TYPE_NET_OPTION_NAME_PERMISSIONS)
); );
if ( realBad ) { break; } if ( realBad ) { break; }
modifierType = type; modifierType = type;
break; break;
case NODE_TYPE_NET_OPTION_NAME_PING: case NODE_TYPE_NET_OPTION_NAME_PING:
case NODE_TYPE_NET_OPTION_NAME_WEBSOCKET: case NODE_TYPE_NET_OPTION_NAME_WEBSOCKET:
realBad = hasValue; realBad = hasValue;
if ( realBad ) { break; } if ( realBad ) { break; }
requestTypeCount += 1; requestTypeCount += 1;
unredirectableTypeCount += 1; unredirectableTypeCount += 1;
break; break;
case NODE_TYPE_NET_OPTION_NAME_POPUNDER: case NODE_TYPE_NET_OPTION_NAME_POPUNDER:
case NODE_TYPE_NET_OPTION_NAME_POPUP: case NODE_TYPE_NET_OPTION_NAME_POPUP:
realBad = hasValue; realBad = hasValue;
if ( realBad ) { break; } if ( realBad ) { break; }
abstractTypeCount += 1; abstractTypeCount += 1;
unredirectableTypeCount += 1; unredirectableTypeCount += 1;
break; break;
case NODE_TYPE_NET_OPTION_NAME_REDIRECT: case NODE_TYPE_NET_OPTION_NAME_REDIRECT:
case NODE_TYPE_NET_OPTION_NAME_REDIRECTRULE: case NODE_TYPE_NET_OPTION_NAME_REDIRECTRULE:
case NODE_TYPE_NET_OPTION_NAME_REPLACE: case NODE_TYPE_NET_OPTION_NAME_REPLACE:
case NODE_TYPE_NET_OPTION_NAME_URLTRANSFORM: case NODE_TYPE_NET_OPTION_NAME_URLTRANSFORM:
realBad = isNegated || (isException || hasValue) === false || realBad = isNegated || (isException || hasValue) === false ||
modifierType !== 0; modifierType !== 0;
if ( realBad ) { break; } if ( realBad ) { break; }
modifierType = type; modifierType = type;
break; break;
case NODE_TYPE_NET_OPTION_NAME_REMOVEPARAM: case NODE_TYPE_NET_OPTION_NAME_REMOVEPARAM:
realBad = isNegated || modifierType !== 0; realBad = isNegated || modifierType !== 0;
if ( realBad ) { break; } if ( realBad ) { break; }
modifierType = type; modifierType = type;
break; break;
case NODE_TYPE_NET_OPTION_NAME_STRICT1P: case NODE_TYPE_NET_OPTION_NAME_STRICT1P:
case NODE_TYPE_NET_OPTION_NAME_STRICT3P: case NODE_TYPE_NET_OPTION_NAME_STRICT3P:
realBad = isNegated || hasValue; realBad = isNegated || hasValue;
break; break;
case NODE_TYPE_NET_OPTION_NAME_UNKNOWN: case NODE_TYPE_NET_OPTION_NAME_UNKNOWN:
this.astError = AST_ERROR_OPTION_UNKNOWN; this.astError = AST_ERROR_OPTION_UNKNOWN;
realBad = true; realBad = true;
break; break;
case NODE_TYPE_NET_OPTION_NAME_WEBRTC: case NODE_TYPE_NET_OPTION_NAME_WEBRTC:
realBad = true; realBad = true;
break; break;
case NODE_TYPE_NET_PATTERN_RAW: case NODE_TYPE_NET_PATTERN_RAW:
realBad = this.hasOptions() === false && realBad = this.hasOptions() === false &&
this.getNetPattern().length <= 1; this.getNetPattern().length <= 1;
break; break;
default: default:
break; break;
} }
if ( bad || realBad ) { if ( bad || realBad ) {
this.addNodeFlags(targetNode, NODE_FLAG_ERROR); this.addNodeFlags(targetNode, NODE_FLAG_ERROR);
@ -1467,64 +1469,64 @@ export class AstFilterParser {
this.options.trustedSource !== true && this.options.trustedSource !== true &&
isException === false && badfilter === false; isException === false && badfilter === false;
switch ( modifierType ) { switch ( modifierType ) {
case NODE_TYPE_NET_OPTION_NAME_CNAME: case NODE_TYPE_NET_OPTION_NAME_CNAME:
realBad = abstractTypeCount || behaviorTypeCount || requestTypeCount; realBad = abstractTypeCount || behaviorTypeCount || requestTypeCount;
break; break;
case NODE_TYPE_NET_OPTION_NAME_CSP: case NODE_TYPE_NET_OPTION_NAME_CSP:
case NODE_TYPE_NET_OPTION_NAME_PERMISSIONS: case NODE_TYPE_NET_OPTION_NAME_PERMISSIONS:
realBad = abstractTypeCount || behaviorTypeCount || requestTypeCount; realBad = abstractTypeCount || behaviorTypeCount || requestTypeCount;
break; break;
case NODE_TYPE_NET_OPTION_NAME_INLINEFONT: case NODE_TYPE_NET_OPTION_NAME_INLINEFONT:
case NODE_TYPE_NET_OPTION_NAME_INLINESCRIPT: case NODE_TYPE_NET_OPTION_NAME_INLINESCRIPT:
realBad = behaviorTypeCount; realBad = behaviorTypeCount;
break; break;
case NODE_TYPE_NET_OPTION_NAME_EMPTY: case NODE_TYPE_NET_OPTION_NAME_EMPTY:
realBad = abstractTypeCount || behaviorTypeCount; realBad = abstractTypeCount || behaviorTypeCount;
break; break;
case NODE_TYPE_NET_OPTION_NAME_MEDIA: case NODE_TYPE_NET_OPTION_NAME_MEDIA:
case NODE_TYPE_NET_OPTION_NAME_MP4: case NODE_TYPE_NET_OPTION_NAME_MP4:
realBad = abstractTypeCount || behaviorTypeCount || docTypeCount || requestTypeCount; realBad = abstractTypeCount || behaviorTypeCount || docTypeCount || requestTypeCount;
break; break;
case NODE_TYPE_NET_OPTION_NAME_REDIRECT: case NODE_TYPE_NET_OPTION_NAME_REDIRECT:
case NODE_TYPE_NET_OPTION_NAME_REDIRECTRULE: { case NODE_TYPE_NET_OPTION_NAME_REDIRECTRULE: {
realBad = abstractTypeCount || behaviorTypeCount || unredirectableTypeCount; realBad = abstractTypeCount || behaviorTypeCount || unredirectableTypeCount;
break;
}
case NODE_TYPE_NET_OPTION_NAME_REPLACE: {
realBad = abstractTypeCount || behaviorTypeCount || unredirectableTypeCount;
if ( realBad ) { break; }
if ( requiresTrustedSource() ) {
this.astError = AST_ERROR_UNTRUSTED_SOURCE;
realBad = true;
break; break;
} }
const value = this.getNetOptionValue(NODE_TYPE_NET_OPTION_NAME_REPLACE); case NODE_TYPE_NET_OPTION_NAME_REPLACE: {
if ( parseReplaceValue(value) === undefined ) { realBad = abstractTypeCount || behaviorTypeCount || unredirectableTypeCount;
this.astError = AST_ERROR_OPTION_BADVALUE; if ( realBad ) { break; }
realBad = true; if ( requiresTrustedSource() ) {
} this.astError = AST_ERROR_UNTRUSTED_SOURCE;
break; realBad = true;
} break;
case NODE_TYPE_NET_OPTION_NAME_URLTRANSFORM: { }
realBad = abstractTypeCount || behaviorTypeCount || unredirectableTypeCount; const value = this.getNetOptionValue(NODE_TYPE_NET_OPTION_NAME_REPLACE);
if ( realBad ) { break; } if ( parseReplaceValue(value) === undefined ) {
if ( requiresTrustedSource() ) { this.astError = AST_ERROR_OPTION_BADVALUE;
this.astError = AST_ERROR_UNTRUSTED_SOURCE; realBad = true;
realBad = true; }
break; break;
} }
const value = this.getNetOptionValue(NODE_TYPE_NET_OPTION_NAME_URLTRANSFORM); case NODE_TYPE_NET_OPTION_NAME_URLTRANSFORM: {
if ( value !== '' && parseReplaceValue(value) === undefined ) { realBad = abstractTypeCount || behaviorTypeCount || unredirectableTypeCount;
this.astError = AST_ERROR_OPTION_BADVALUE; if ( realBad ) { break; }
realBad = true; if ( requiresTrustedSource() ) {
this.astError = AST_ERROR_UNTRUSTED_SOURCE;
realBad = true;
break;
}
const value = this.getNetOptionValue(NODE_TYPE_NET_OPTION_NAME_URLTRANSFORM);
if ( value !== '' && parseReplaceValue(value) === undefined ) {
this.astError = AST_ERROR_OPTION_BADVALUE;
realBad = true;
}
break;
} }
break; case NODE_TYPE_NET_OPTION_NAME_REMOVEPARAM:
} realBad = abstractTypeCount || behaviorTypeCount;
case NODE_TYPE_NET_OPTION_NAME_REMOVEPARAM: break;
realBad = abstractTypeCount || behaviorTypeCount; default:
break; break;
default:
break;
} }
if ( realBad ) { if ( realBad ) {
const targetNode = this.getBranchFromType(modifierType); const targetNode = this.getBranchFromType(modifierType);
@ -2059,15 +2061,15 @@ export class AstFilterParser {
parentBeg + optionEnd parentBeg + optionEnd
); );
switch ( nodeOptionType ) { switch ( nodeOptionType ) {
case NODE_TYPE_NET_OPTION_NAME_DENYALLOW: case NODE_TYPE_NET_OPTION_NAME_DENYALLOW:
this.linkDown(next, this.parseDomainList(next, '|'), 0b00000); this.linkDown(next, this.parseDomainList(next, '|'), 0b00000);
break; break;
case NODE_TYPE_NET_OPTION_NAME_FROM: case NODE_TYPE_NET_OPTION_NAME_FROM:
case NODE_TYPE_NET_OPTION_NAME_TO: case NODE_TYPE_NET_OPTION_NAME_TO:
this.linkDown(next, this.parseDomainList(next, '|', 0b11010)); this.linkDown(next, this.parseDomainList(next, '|', 0b11010));
break; break;
default: default:
break; break;
} }
this.linkRight(prev, next); this.linkRight(prev, next);
return this.throwHeadNode(head); return this.throwHeadNode(head);
@ -2282,27 +2284,27 @@ export class AstFilterParser {
if ( (flags & NODE_FLAG_ERROR) !== 0 ) { continue; } if ( (flags & NODE_FLAG_ERROR) !== 0 ) { continue; }
realBad = false; realBad = false;
switch ( type ) { switch ( type ) {
case NODE_TYPE_EXT_PATTERN_RESPONSEHEADER: { case NODE_TYPE_EXT_PATTERN_RESPONSEHEADER: {
const pattern = this.getNodeString(targetNode); const pattern = this.getNodeString(targetNode);
realBad = realBad =
pattern !== '' && removableHTTPHeaders.has(pattern) === false || pattern !== '' && removableHTTPHeaders.has(pattern) === false ||
pattern === '' && isException === false; pattern === '' && isException === false;
break; break;
}
case NODE_TYPE_EXT_PATTERN_SCRIPTLET_TOKEN: {
if ( this.interactive !== true ) { break; }
if ( isException ) { break; }
const { trustedSource, trustedScriptletTokens } = this.options;
if ( trustedScriptletTokens instanceof Set === false ) { break; }
const token = this.getNodeString(targetNode);
if ( trustedScriptletTokens.has(token) && trustedSource !== true ) {
this.astError = AST_ERROR_UNTRUSTED_SOURCE;
realBad = true;
} }
break; case NODE_TYPE_EXT_PATTERN_SCRIPTLET_TOKEN: {
} if ( this.interactive !== true ) { break; }
default: if ( isException ) { break; }
break; const { trustedSource, trustedScriptletTokens } = this.options;
if ( trustedScriptletTokens instanceof Set === false ) { break; }
const token = this.getNodeString(targetNode);
if ( trustedScriptletTokens.has(token) && trustedSource !== true ) {
this.astError = AST_ERROR_UNTRUSTED_SOURCE;
realBad = true;
}
break;
}
default:
break;
} }
if ( realBad ) { if ( realBad ) {
this.addNodeFlags(targetNode, NODE_FLAG_ERROR); this.addNodeFlags(targetNode, NODE_FLAG_ERROR);
@ -2418,7 +2420,7 @@ export class AstFilterParser {
parentBeg + argsEnd parentBeg + argsEnd
); );
this.linkDown(next, this.parseExtPatternScriptletArglist(next)); this.linkDown(next, this.parseExtPatternScriptletArglist(next));
this.linkRight(prev, next); prev = this.linkRight(prev, next);
return this.throwHeadNode(head); return this.throwHeadNode(head);
} }
@ -2472,12 +2474,12 @@ export class AstFilterParser {
const walker = this.getWalker(root); const walker = this.getWalker(root);
for ( let node = walker.next(); node !== 0; node = walker.next() ) { for ( let node = walker.next(); node !== 0; node = walker.next() ) {
switch ( this.getNodeType(node) ) { switch ( this.getNodeType(node) ) {
case NODE_TYPE_EXT_PATTERN_SCRIPTLET_TOKEN: case NODE_TYPE_EXT_PATTERN_SCRIPTLET_TOKEN:
case NODE_TYPE_EXT_PATTERN_SCRIPTLET_ARG: case NODE_TYPE_EXT_PATTERN_SCRIPTLET_ARG:
args.push(this.getNodeTransform(node)); args.push(this.getNodeTransform(node));
break; break;
default: default:
break; break;
} }
} }
walker.dispose(); walker.dispose();
@ -3204,7 +3206,6 @@ class ExtSelectorCompiler {
'matches-css-before', 'matches-css-before',
'matches-media', 'matches-media',
'matches-path', 'matches-path',
'matches-prop',
'min-text-length', 'min-text-length',
'others', 'others',
'shadow', 'shadow',
@ -3841,7 +3842,6 @@ class ExtSelectorCompiler {
case 'if-not': case 'if-not':
return this.compileSelector(arg); return this.compileSelector(arg);
case 'matches-attr': case 'matches-attr':
case 'matches-prop':
return this.compileMatchAttrArgument(arg); return this.compileMatchAttrArgument(arg);
case 'matches-css': case 'matches-css':
return this.compileCSSDeclaration(arg); return this.compileCSSDeclaration(arg);
@ -4037,7 +4037,7 @@ class ExtSelectorCompiler {
compileAttrList(s) { compileAttrList(s) {
if ( s === '' ) { return s; } if ( s === '' ) { return s; }
const attrs = s.split(/\s*,\s*/); const attrs = s.split('\s*,\s*');
const out = []; const out = [];
for ( const attr of attrs ) { for ( const attr of attrs ) {
if ( attr !== '' ) { if ( attr !== '' ) {
@ -4075,7 +4075,6 @@ export const proceduralOperatorTokens = new Map([
[ 'matches-css', 0b11 ], [ 'matches-css', 0b11 ],
[ 'matches-media', 0b11 ], [ 'matches-media', 0b11 ],
[ 'matches-path', 0b11 ], [ 'matches-path', 0b11 ],
[ 'matches-prop', 0b11 ],
[ 'min-text-length', 0b01 ], [ 'min-text-length', 0b01 ],
[ 'not', 0b01 ], [ 'not', 0b01 ],
[ 'nth-ancestor', 0b00 ], [ 'nth-ancestor', 0b00 ],