Browse Source

LibWeb: Fix crash parsing an invalid pseudo compound selector

Reduced from a crash on: https://github.com/SerenityOS/serenity/pulls

Fixes #20568
Shannon Booth 1 year ago
parent
commit
576f8e8fa8

+ 11 - 0
Tests/LibWeb/Layout/expected/css-invalid-psuedo-compound-selector.txt

@@ -0,0 +1,11 @@
+Viewport <#document> at (0,0) content-size 800x600 children: not-inline
+  BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
+    BlockContainer <body> at (8,8) content-size 784x0 children: not-inline
+      BlockContainer <div> at (8,8) content-size 784x0 children: inline
+        TextNode <#text>
+        TextNode <#text>
+
+PaintableWithLines (Viewport<#document>) [0,0 800x600]
+  PaintableWithLines (BlockContainer<HTML>) [0,0 800x600]
+    PaintableWithLines (BlockContainer<BODY>) [8,8 784x0]
+      PaintableWithLines (BlockContainer<DIV>) [8,8 784x0]

+ 5 - 0
Tests/LibWeb/Layout/input/css-invalid-psuedo-compound-selector.html

@@ -0,0 +1,5 @@
+<div>
+<style>
+:host(:thing) {}
+</style>
+</div>

+ 3 - 3
Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp

@@ -635,13 +635,13 @@ Parser::ParseErrorOr<Selector::SimpleSelector> Parser::parse_pseudo_simple_selec
             return parse_nth_child_selector(pseudo_class, pseudo_function.values(), true);
         case PseudoClassMetadata::ParameterType::CompoundSelector: {
             auto function_token_stream = TokenStream(pseudo_function.values());
-            auto compound_selector = MUST(parse_compound_selector(function_token_stream));
-            if (!compound_selector.has_value()) {
+            auto compound_selector_or_error = parse_compound_selector(function_token_stream);
+            if (compound_selector_or_error.is_error() || !compound_selector_or_error.value().has_value()) {
                 dbgln_if(CSS_PARSER_DEBUG, "Failed to parse :{}() parameter as a compound selector", pseudo_function.name());
                 return ParseError::SyntaxError;
             }
 
-            Vector compound_selectors { compound_selector.release_value() };
+            Vector compound_selectors { compound_selector_or_error.release_value().release_value() };
             auto selector = Selector::create(move(compound_selectors));
 
             return Selector::SimpleSelector {