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.
This commit is contained in:
Timothy Flynn 2021-10-29 08:38:50 -04:00 committed by Andreas Kling
parent 1e6afa9fd5
commit eb0fb38cac
Notes: sideshowbarker 2024-07-18 01:45:31 +09:00
2 changed files with 28 additions and 11 deletions

View file

@ -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.

View file

@ -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&);