From 361fc566324ef0273c4a972efd43651a326ec038 Mon Sep 17 00:00:00 2001 From: MacDue Date: Sun, 7 Aug 2022 23:31:16 +0100 Subject: LibWeb: Don't allow mixed commas/no commas in rect() css values This fixes the clip-rect-comma-002, clip-rect-comma-003, and clip-rect-comma-004 web platform tests. --- Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp | 43 +++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 7389134c2d..7aa1ff4ab7 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -3363,10 +3363,25 @@ RefPtr Parser::parse_rect_value(ComponentValue const& component_valu Vector params; auto tokens = TokenStream { function.values() }; + enum class CommaRequirement { + Unknown, + RequiresCommas, + RequiresNoCommas + }; + + enum class Side { + Top = 0, + Right = 1, + Bottom = 2, + Left = 3 + }; + + auto comma_requirement = CommaRequirement::Unknown; + // In CSS 2.1, the only valid value is: rect(, , , ) where // and specify offsets from the top border edge of the box, and , and // specify offsets from the left border edge of the box. - for (size_t idx = 0; idx < 4; idx++) { + for (size_t side = 0; side < 4; side++) { tokens.skip_whitespace(); // , , , and may either have a value or 'auto'. @@ -3382,12 +3397,34 @@ RefPtr Parser::parse_rect_value(ComponentValue const& component_valu } tokens.skip_whitespace(); + // The last side, should be no more tokens following it. + if (static_cast(side) == Side::Left) { + if (tokens.has_next_token()) + return {}; + break; + } + + bool next_is_comma = tokens.peek_token().is(Token::Type::Comma); + // Authors should separate offset values with commas. User agents must support separation // with commas, but may also support separation without commas (but not a combination), // because a previous revision of this specification was ambiguous in this respect. - if (tokens.peek_token().is(Token::Type::Comma)) - tokens.next_token(); + if (comma_requirement == CommaRequirement::Unknown) + comma_requirement = next_is_comma ? CommaRequirement::RequiresCommas : CommaRequirement::RequiresNoCommas; + + if (comma_requirement == CommaRequirement::RequiresCommas) { + if (next_is_comma) + tokens.next_token(); + else + return {}; + } else if (comma_requirement == CommaRequirement::RequiresNoCommas) { + if (next_is_comma) + return {}; + } else { + VERIFY_NOT_REACHED(); + } } + return RectStyleValue::create(EdgeRect { params[0], params[1], params[2], params[3] }); } -- cgit v1.2.3