From 09a5c04e5c306d5d58d7728e7be51925e0d79d9b Mon Sep 17 00:00:00 2001 From: Callum Law Date: Thu, 10 Jul 2025 17:04:57 +1200 Subject: [PATCH] LibWeb: Handle serialization of invalid font-variant in all contexts Previously as we handled this in `get_property_internal` there were some contexts that we missed, for instance `CSSStyleProperties::serialized`. --- Libraries/LibWeb/CSS/CSSStyleProperties.cpp | 34 ------------------- .../CSS/StyleValues/ShorthandStyleValue.cpp | 4 +++ .../css/invalid-font-variant-css-text.txt | 1 + .../css/invalid-font-variant-css-text.html | 16 +++++++++ 4 files changed, 21 insertions(+), 34 deletions(-) create mode 100644 Tests/LibWeb/Text/expected/css/invalid-font-variant-css-text.txt create mode 100644 Tests/LibWeb/Text/input/css/invalid-font-variant-css-text.html diff --git a/Libraries/LibWeb/CSS/CSSStyleProperties.cpp b/Libraries/LibWeb/CSS/CSSStyleProperties.cpp index bd92141a291..8a6c9cdf852 100644 --- a/Libraries/LibWeb/CSS/CSSStyleProperties.cpp +++ b/Libraries/LibWeb/CSS/CSSStyleProperties.cpp @@ -509,40 +509,6 @@ Optional CSSStyleProperties::get_property_internal(PropertyID pro auto left = get_property_internal(PropertyID::BorderLeftWidth); return style_property_for_sided_shorthand(property_id, top, right, bottom, left); } - case PropertyID::FontVariant: { - auto ligatures = get_property_internal(PropertyID::FontVariantLigatures); - auto caps = get_property_internal(PropertyID::FontVariantCaps); - auto alternates = get_property_internal(PropertyID::FontVariantAlternates); - auto numeric = get_property_internal(PropertyID::FontVariantNumeric); - auto east_asian = get_property_internal(PropertyID::FontVariantEastAsian); - auto position = get_property_internal(PropertyID::FontVariantPosition); - auto emoji = get_property_internal(PropertyID::FontVariantEmoji); - - if (!ligatures.has_value() || !caps.has_value() || !alternates.has_value() || !numeric.has_value() || !east_asian.has_value() || !position.has_value() || !emoji.has_value()) - return {}; - - if (ligatures->important != caps->important || ligatures->important != alternates->important || ligatures->important != numeric->important || ligatures->important != east_asian->important || ligatures->important != position->important || ligatures->important != emoji->important) - return {}; - - // If ligatures is `none` and any other value isn't `normal`, that's invalid. - if (ligatures->value->to_keyword() == Keyword::None - && (caps->value->to_keyword() != Keyword::Normal - || alternates->value->to_keyword() != Keyword::Normal - || numeric->value->to_keyword() != Keyword::Normal - || east_asian->value->to_keyword() != Keyword::Normal - || position->value->to_keyword() != Keyword::Normal - || emoji->value->to_keyword() != Keyword::Normal)) { - return {}; - } - - return StyleProperty { - .important = ligatures->important, - .property_id = property_id, - .value = ShorthandStyleValue::create(property_id, - { PropertyID::FontVariantLigatures, PropertyID::FontVariantCaps, PropertyID::FontVariantAlternates, PropertyID::FontVariantNumeric, PropertyID::FontVariantEastAsian, PropertyID::FontVariantPosition, PropertyID::FontVariantEmoji }, - { ligatures->value, caps->value, alternates->value, numeric->value, east_asian->value, position->value, emoji->value }) - }; - } case PropertyID::Margin: { auto top = get_property_internal(PropertyID::MarginTop); auto right = get_property_internal(PropertyID::MarginRight); diff --git a/Libraries/LibWeb/CSS/StyleValues/ShorthandStyleValue.cpp b/Libraries/LibWeb/CSS/StyleValues/ShorthandStyleValue.cpp index ebf9c2f48d3..60e745b8325 100644 --- a/Libraries/LibWeb/CSS/StyleValues/ShorthandStyleValue.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/ShorthandStyleValue.cpp @@ -344,6 +344,10 @@ String ShorthandStyleValue::to_string(SerializationMode mode) const auto position = longhand(PropertyID::FontVariantPosition); auto emoji = longhand(PropertyID::FontVariantEmoji); + // If ligatures is `none` and any other value isn't `normal`, that's invalid. + if (ligatures->to_keyword() == Keyword::None && !first_is_equal_to_all_of(Keyword::Normal, caps->to_keyword(), alternates->to_keyword(), numeric->to_keyword(), east_asian->to_keyword(), position->to_keyword(), emoji->to_keyword())) + return ""_string; + Vector values; if (ligatures->to_keyword() != Keyword::Normal) values.append(ligatures->to_string(mode)); diff --git a/Tests/LibWeb/Text/expected/css/invalid-font-variant-css-text.txt b/Tests/LibWeb/Text/expected/css/invalid-font-variant-css-text.txt new file mode 100644 index 00000000000..47770b13c7c --- /dev/null +++ b/Tests/LibWeb/Text/expected/css/invalid-font-variant-css-text.txt @@ -0,0 +1 @@ +#foo { font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-variant-ligatures: none; font-variant-caps: all-petite-caps; } diff --git a/Tests/LibWeb/Text/input/css/invalid-font-variant-css-text.html b/Tests/LibWeb/Text/input/css/invalid-font-variant-css-text.html new file mode 100644 index 00000000000..b7f9b15dd68 --- /dev/null +++ b/Tests/LibWeb/Text/input/css/invalid-font-variant-css-text.html @@ -0,0 +1,16 @@ + + + + + +