From ea101c6336b438c90bc0ad0175300c7600d70808 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Tue, 3 Jun 2025 13:07:04 +0100 Subject: [PATCH] LibWeb/CSS: Limit string values for font format() to the spec's set A couple of differences from before: - Only the fixed set of strings are allowed. Some formats can only be an ident (eg, svg). - We don't allow these foo-variations values in ident form. - The comparison is done case-insensitively. It's unclear if this is more or less correct, but as most things in CSS are insensitive, including idents, it makes sense that these would be too. --- Libraries/LibWeb/CSS/Parser/ValueParsing.cpp | 44 ++++++++++++++++---- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/Libraries/LibWeb/CSS/Parser/ValueParsing.cpp b/Libraries/LibWeb/CSS/Parser/ValueParsing.cpp index 1e6734d1e39..686eb1738a8 100644 --- a/Libraries/LibWeb/CSS/Parser/ValueParsing.cpp +++ b/Libraries/LibWeb/CSS/Parser/ValueParsing.cpp @@ -3917,18 +3917,48 @@ RefPtr Parser::parse_font_source_value(TokenStream format(woff2) + // format("woff") -> format(woff) + // format("truetype") -> format(truetype) + // format("opentype") -> format(opentype) + // format("collection") -> format(collection) + // format("woff2-variations") -> format(woff2) tech(variations) + // format("woff-variations") -> format(woff) tech(variations) + // format("truetype-variations") -> format(truetype) tech(variations) + // format("opentype-variations") -> format(opentype) tech(variations) + if (name_string.equals_ignoring_ascii_case("woff2"sv)) { + format_name = "woff2"_fly_string; + } else if (name_string.equals_ignoring_ascii_case("woff"sv)) { + format_name = "woff"_fly_string; + } else if (name_string.equals_ignoring_ascii_case("truetype"sv)) { + format_name = "truetype"_fly_string; + } else if (name_string.equals_ignoring_ascii_case("opentype"sv)) { + format_name = "opentype"_fly_string; + } else if (name_string.equals_ignoring_ascii_case("collection"sv)) { + format_name = "collection"_fly_string; + } else if (name_string.equals_ignoring_ascii_case("woff2-variations"sv)) { + format_name = "woff2"_fly_string; + tech.append(FontTech::Variations); + } else if (name_string.equals_ignoring_ascii_case("woff-variations"sv)) { + format_name = "woff"_fly_string; + tech.append(FontTech::Variations); + } else if (name_string.equals_ignoring_ascii_case("truetype-variations"sv)) { + format_name = "truetype"_fly_string; + tech.append(FontTech::Variations); + } else if (name_string.equals_ignoring_ascii_case("opentype-variations"sv)) { + format_name = "opentype"_fly_string; + tech.append(FontTech::Variations); + } else { + dbgln_if(CSS_PARSER_DEBUG, "CSSParser: font source invalid (`format()` parameter \"{}\" is not in the set of valid strings); skipping.", name_string); + return nullptr; + } } else { dbgln_if(CSS_PARSER_DEBUG, "CSSParser: font source invalid (`format()` parameter not an ident or string; is: {}); discarding.", format_name_token.to_debug_string()); return nullptr; } - // NOTE: Some of the formats support an optional "-variations" suffix that's really supposed to map to tech(variations). - if (format_name.is_one_of("woff2-variations"sv, "woff-variations"sv, "truetype-variations"sv, "opentype-variations"sv)) { - format_name = MUST(format_name.to_string().substring_from_byte_offset(0, format_name.bytes().size() - strlen("-variations"))); - tech.append(FontTech::Variations); - } - if (!font_format_is_supported(format_name)) { dbgln_if(CSS_PARSER_DEBUG, "CSSParser: font source format({}) not supported; skipping.", format_name); return nullptr;