From 9c58f0c635ed45f02098b17f2e49c1f86b699771 Mon Sep 17 00:00:00 2001 From: David Shin Date: Mon, 15 May 2023 13:33:01 +0000 Subject: [PATCH] style: Disallow :has selector nesting Unlike the `ParseRelative` flag, which turns on relative selector parsing for that parsing level only, the newly added `DISALLOW_RELATIVE_SELECTOR` flag propagates through nested parsing calls. Differential Revision: https://phabricator.services.mozilla.com/D176807 --- components/selectors/parser.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/components/selectors/parser.rs b/components/selectors/parser.rs index 8f0d296d740..f9f316b52b3 100644 --- a/components/selectors/parser.rs +++ b/components/selectors/parser.rs @@ -119,6 +119,9 @@ bitflags! { /// Whether we explicitly disallow pseudo-element-like things. const DISALLOW_PSEUDOS = 1 << 6; + + /// Whether we explicitly disallow relative selectors (i.e. `:has()`). + const DISALLOW_RELATIVE_SELECTOR = 1 << 7; } } @@ -2942,12 +2945,20 @@ where Impl: SelectorImpl, { debug_assert!(parser.parse_has()); + if state.intersects(SelectorParsingState::DISALLOW_RELATIVE_SELECTOR) { + return Err(input.new_custom_error(SelectorParseErrorKind::InvalidState)); + } + // Nested `:has()` is disallowed, mark it as such. + // Note: The spec defines ":has-allowed pseudo-element," but there's no + // pseudo-element defined as such at the moment. + // https://w3c.github.io/csswg-drafts/selectors-4/#has-allowed-pseudo-element let inner = SelectorList::parse_with_state( parser, input, state | SelectorParsingState::SKIP_DEFAULT_NAMESPACE | - SelectorParsingState::DISALLOW_PSEUDOS, + SelectorParsingState::DISALLOW_PSEUDOS | + SelectorParsingState::DISALLOW_RELATIVE_SELECTOR, ForgivingParsing::No, ParseRelative::Yes, )?;