From 308c2eab0ef705f66784e8f25d76d4f9e04476e7 Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Thu, 4 Sep 2025 13:16:23 +0200 Subject: [PATCH] LibWeb: Throw parsing error if `::slotted()` argument is not 1 compound ...selector. Grammar per spec: `::slotted( )`, so we should reject selector as invalid if first compound selector is followed by something else. This change makes layout more correct on https://www.rottentomatoes.com/ --- .../LibWeb/CSS/Parser/SelectorParsing.cpp | 9 +++++ .../misc/invalid-slotted-selector.txt | 34 +++++++++++++++++++ .../input/misc/invalid-slotted-selector.html | 11 ++++++ 3 files changed, 54 insertions(+) create mode 100644 Tests/LibWeb/Layout/expected/misc/invalid-slotted-selector.txt create mode 100644 Tests/LibWeb/Layout/input/misc/invalid-slotted-selector.html diff --git a/Libraries/LibWeb/CSS/Parser/SelectorParsing.cpp b/Libraries/LibWeb/CSS/Parser/SelectorParsing.cpp index d85ff71f6a2..7bf779dc34d 100644 --- a/Libraries/LibWeb/CSS/Parser/SelectorParsing.cpp +++ b/Libraries/LibWeb/CSS/Parser/SelectorParsing.cpp @@ -517,6 +517,15 @@ Parser::ParseErrorOr Parser::parse_pseudo_simple_selec }); return ParseError::SyntaxError; } + function_tokens.discard_whitespace(); + if (function_tokens.has_next_token()) { + ErrorReporter::the().report(InvalidPseudoClassOrElementError { + .name = MUST(String::formatted("::{}", pseudo_name)), + .value_string = name_token.to_string(), + .description = "Trailing tokens after compound selector argument."_string, + }); + return ParseError::SyntaxError; + } auto compound_selector = compound_selector_or_error.release_value().release_value(); compound_selector.combinator = Selector::Combinator::None; diff --git a/Tests/LibWeb/Layout/expected/misc/invalid-slotted-selector.txt b/Tests/LibWeb/Layout/expected/misc/invalid-slotted-selector.txt new file mode 100644 index 00000000000..26e8e17744d --- /dev/null +++ b/Tests/LibWeb/Layout/expected/misc/invalid-slotted-selector.txt @@ -0,0 +1,34 @@ +Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] children: not-inline + BlockContainer at [0,0] [0+0+0 800 0+0+0] [0+0+0 50 0+0+0] [BFC] children: not-inline + BlockContainer at [8,16] [8+0+0 784 0+0+8] [8+0+0 18 0+0+16] children: not-inline + BlockContainer
at [8,16] [0+0+0 784 0+0+0] [0+0+0 18 0+0+0] children: not-inline + Box