LibWeb: Include "url(" in the original source text of URL tokens

When we invoke Tokenizer::consume_a_url_token, we have already consumed
the "url(" text from the source. Thus we would set the original source
text to the text starting just after those consumed code points. Let's
instead pass in the known starting position from the caller.

This fixes a bug seen on https://lichess.org, where they perform a
`substring(4)` on the property value to remove the "url(" text. This
would strip away the "http" part of the URL, and we would try to load
"s://lichess.org/image.svg". With this fixed, we can play chess games
on this site.
This commit is contained in:
Timothy Flynn 2025-12-10 14:26:48 -05:00 committed by Jelle Raaijmakers
parent 4249b14907
commit 7114872073
4 changed files with 21 additions and 4 deletions

View file

@ -410,7 +410,7 @@ Token Tokenizer::consume_an_ident_like_token()
}
// Otherwise, consume a url token, and return it.
return consume_a_url_token();
return consume_a_url_token(start_byte_offset);
}
// Otherwise, if the next input code point is U+0028 LEFT PARENTHESIS ((), consume it.
@ -576,7 +576,7 @@ FlyString Tokenizer::consume_an_ident_sequence()
}
// https://www.w3.org/TR/css-syntax-3/#consume-url-token
Token Tokenizer::consume_a_url_token()
Token Tokenizer::consume_a_url_token(size_t start_byte_offset)
{
// This section describes how to consume a url token from a stream of code points.
// It returns either a <url-token> or a <bad-url-token>.
@ -588,7 +588,6 @@ Token Tokenizer::consume_a_url_token()
// shouldnt be called directly otherwise.
// 1. Initially create a <url-token> with its value set to the empty string.
auto start_byte_offset = current_byte_offset();
StringBuilder builder;
// 2. Consume as much whitespace as possible.

View file

@ -88,7 +88,7 @@ private:
[[nodiscard]] double convert_a_string_to_a_number(StringView);
[[nodiscard]] FlyString consume_an_ident_sequence();
[[nodiscard]] u32 consume_escaped_code_point();
[[nodiscard]] Token consume_a_url_token();
[[nodiscard]] Token consume_a_url_token(size_t start_byte_offset);
void consume_the_remnants_of_a_bad_url();
void consume_comments();
void consume_as_much_whitespace_as_possible();

View file

@ -0,0 +1,2 @@
url("image.svg")
url(image.svg)

View file

@ -0,0 +1,16 @@
<!DOCTYPE html>
<style>
:root {
--style-1: url("image.svg");
--style-2: url(image.svg);
}
</style>
<body></body>
<script src="../include.js"></script>
<script>
test(() => {
const style = window.getComputedStyle(document.body);
println(style.getPropertyValue("--style-1"));
println(style.getPropertyValue("--style-2"));
});
</script>