Detect invalid usage of combinators in :not() pseudoclass

Related feedback:
- https://www.reddit.com/r/uBlockOrigin/comments/z2ttcx/
This commit is contained in:
Raymond Hill 2022-11-25 10:21:58 -05:00
parent 96fdae726a
commit 62601639f6
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
1 changed files with 31 additions and 16 deletions

View File

@ -1547,8 +1547,9 @@ Parser.prototype.SelectorCompiler = class {
} }
if ( data.type !== 'PseudoClassSelector' ) { return; } if ( data.type !== 'PseudoClassSelector' ) { return; }
// Post-analysis // Post-analysis, mind:
// Mind https://w3c.github.io/csswg-drafts/selectors-4/#has-pseudo // - https://w3c.github.io/csswg-drafts/selectors-4/#has-pseudo
// - https://w3c.github.io/csswg-drafts/selectors-4/#negation
data.name = this.normalizedOperators.get(data.name) || data.name; data.name = this.normalizedOperators.get(data.name) || data.name;
if ( this.proceduralOperatorNames.has(data.name) ) { if ( this.proceduralOperatorNames.has(data.name) ) {
data.type = 'ProceduralSelector'; data.type = 'ProceduralSelector';
@ -1558,20 +1559,30 @@ Parser.prototype.SelectorCompiler = class {
data.type = 'Error'; data.type = 'Error';
return; return;
} }
if ( this.maybeProceduralOperatorNames.has(data.name) ) { if ( this.maybeProceduralOperatorNames.has(data.name) === false ) {
if ( this.astHasType(args, 'ProceduralSelector') ) { return;
}
if ( this.astHasType(args, 'ProceduralSelector') ) {
data.type = 'ProceduralSelector';
return;
}
switch ( data.name ) {
case 'has':
if (
this.asProcedural ||
this.nativeCssHas !== true ||
this.astHasName(args, 'has')
) {
data.type = 'ProceduralSelector'; data.type = 'ProceduralSelector';
} else if ( data.name === 'has' ) { } else if ( this.astHasType(args, 'PseudoElementSelector') ) {
if ( data.type = 'Error';
this.asProcedural ||
this.nativeCssHas !== true ||
this.astHasName(args, 'has')
) {
data.type = 'ProceduralSelector';
} else if ( this.astHasType(args, 'PseudoElementSelector') ) {
data.type = 'Error';
}
} }
break;
case 'not':
if ( this.astHasType(args, 'Combinator', 0) ) {
data.type = 'Error';
}
break;
} }
} }
@ -1768,11 +1779,15 @@ Parser.prototype.SelectorCompiler = class {
return out; return out;
} }
astHasType(parts, type) { astHasType(parts, type, depth = 0x7FFFFFFF) {
if ( Array.isArray(parts) === false ) { return false; } if ( Array.isArray(parts) === false ) { return false; }
for ( const part of parts ) { for ( const part of parts ) {
if ( part.data.type === type ) { return true; } if ( part.data.type === type ) { return true; }
if ( Array.isArray(part.args) && this.astHasType(part.args, type) ) { if (
Array.isArray(part.args) &&
depth !== 0 &&
this.astHasType(part.args, type, depth-1)
) {
return true; return true;
} }
} }