Bladeren bron

LibWeb: Support parsing some data: URLs in CSS

For now, data URLs are explicitly limited to expected MIME types. For
example, image-related styles accept image MIME types.
Timothy Flynn 3 jaren geleden
bovenliggende
commit
eb0fb38cac
2 gewijzigde bestanden met toevoegingen van 28 en 11 verwijderingen
  1. 22 10
      Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
  2. 6 1
      Userland/Libraries/LibWeb/CSS/Parser/Parser.h

+ 22 - 10
Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp

@@ -1706,20 +1706,34 @@ Vector<Vector<StyleComponentValueRule>> Parser::parse_a_comma_separated_list_of_
     return lists;
 }
 
-Optional<AK::URL> Parser::parse_url_function(ParsingContext const& context, StyleComponentValueRule const& component_value)
+Optional<AK::URL> Parser::parse_url_function(ParsingContext const& context, StyleComponentValueRule const& component_value, AllowedDataUrlType allowed_data_url_type)
 {
     // FIXME: Handle list of media queries. https://www.w3.org/TR/css-cascade-3/#conditional-import
     // FIXME: Handle data: urls (RFC2397)
 
-    auto is_data_url = [](StringView& url_string) -> bool {
-        return url_string.starts_with("data:", CaseSensitivity::CaseInsensitive);
+    auto convert_string_to_url = [&](StringView& url_string) -> Optional<AK::URL> {
+        if (url_string.starts_with("data:", CaseSensitivity::CaseInsensitive)) {
+            auto data_url = AK::URL(url_string);
+
+            switch (allowed_data_url_type) {
+            case AllowedDataUrlType::Image:
+                if (data_url.data_mime_type().starts_with("image"sv, CaseSensitivity::CaseInsensitive))
+                    return data_url;
+                break;
+
+            default:
+                break;
+            }
+
+            return {};
+        }
+
+        return context.complete_url(url_string);
     };
 
     if (component_value.is(Token::Type::Url)) {
         auto url_string = component_value.token().url();
-        if (is_data_url(url_string))
-            return {};
-        return context.complete_url(url_string);
+        return convert_string_to_url(url_string);
     }
     if (component_value.is_function() && component_value.function().name().equals_ignoring_case("url")) {
         auto& function_values = component_value.function().values();
@@ -1730,9 +1744,7 @@ Optional<AK::URL> Parser::parse_url_function(ParsingContext const& context, Styl
                 continue;
             if (value.is(Token::Type::String)) {
                 auto url_string = value.token().string();
-                if (is_data_url(url_string))
-                    return {};
-                return context.complete_url(url_string);
+                return convert_string_to_url(url_string);
             }
             break;
         }
@@ -2370,7 +2382,7 @@ RefPtr<StyleValue> Parser::parse_string_value(ParsingContext const&, StyleCompon
 
 RefPtr<StyleValue> Parser::parse_image_value(ParsingContext const& context, StyleComponentValueRule const& component_value)
 {
-    auto url = parse_url_function(context, component_value);
+    auto url = parse_url_function(context, component_value, AllowedDataUrlType::Image);
     if (url.has_value())
         return ImageStyleValue::create(url.value());
     // FIXME: Handle gradients.

+ 6 - 1
Userland/Libraries/LibWeb/CSS/Parser/Parser.h

@@ -195,7 +195,12 @@ private:
     static Optional<float> try_parse_float(StringView string);
     static Optional<Color> parse_color(ParsingContext const&, StyleComponentValueRule const&);
     static Optional<Length> parse_length(ParsingContext const&, StyleComponentValueRule const&);
-    static Optional<AK::URL> parse_url_function(ParsingContext const&, StyleComponentValueRule const&);
+
+    enum class AllowedDataUrlType {
+        None,
+        Image,
+    };
+    static Optional<AK::URL> parse_url_function(ParsingContext const&, StyleComponentValueRule const&, AllowedDataUrlType = AllowedDataUrlType::None);
 
     Result<NonnullRefPtr<StyleValue>, ParsingResult> parse_css_value(PropertyID, TokenStream<StyleComponentValueRule>&);
     static RefPtr<StyleValue> parse_css_value(ParsingContext const&, StyleComponentValueRule const&);