From 5d6a4c5fc2deb7c63e29f7f55f98f24afebb7999 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Wed, 22 Sep 2021 20:25:58 +0100 Subject: [PATCH] LibWeb: Check parsed CSS values with property_accepts_value() This brings us a few nice benefits: - We only generate a `StyleValueList` for properties that accept multiple values. - We reject declarations that have too many values. - We check the type of each value that is parsed, to make sure it's acceptable to the property. Probably there are some regressions here, since this is Later, we can also replace many of the `is_foo()` functions and lambas inside the Parser with more calls to `property_accepts_value()`. Also we can remove some checks when resolving styles, since only valid types of values will get to that point. But one step at a time. :^) --- .../Libraries/LibWeb/CSS/Parser/Parser.cpp | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index d2640a7826..e99043d532 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -2872,22 +2872,25 @@ Result, Parser::ParsingResult> Parser::parse_css_value } if (component_values.size() == 1) { - if (auto parsed_value = parse_css_value(m_context, component_values.first())) - return parsed_value.release_nonnull(); + if (auto parsed_value = parse_css_value(m_context, component_values.first())) { + if (property_accepts_value(property_id, *parsed_value)) + return parsed_value.release_nonnull(); + } return ParsingResult::SyntaxError; } // We have multiple values, so treat them as a StyleValueList. - // FIXME: Specify in Properties.json whether to permit this for each property. - NonnullRefPtrVector parsed_values; - for (auto& component_value : component_values) { - auto parsed = parse_css_value(m_context, component_value); - if (!parsed) - return ParsingResult::SyntaxError; - parsed_values.append(parsed.release_nonnull()); + if (property_maximum_value_count(property_id) > 1) { + NonnullRefPtrVector parsed_values; + for (auto& component_value : component_values) { + auto parsed_value = parse_css_value(m_context, component_value); + if (!parsed_value || !property_accepts_value(property_id, *parsed_value)) + return ParsingResult::SyntaxError; + parsed_values.append(parsed_value.release_nonnull()); + } + if (!parsed_values.is_empty() && parsed_values.size() <= property_maximum_value_count(property_id)) + return { StyleValueList::create(move(parsed_values)) }; } - if (!parsed_values.is_empty()) - return { StyleValueList::create(move(parsed_values)) }; return ParsingResult::SyntaxError; }