From eb41f0144ba6f6f7f24f8f9f3e658f366d9d002c Mon Sep 17 00:00:00 2001 From: Karol Kosek Date: Thu, 6 Jul 2023 19:11:58 +0200 Subject: [PATCH] AK: Decode data URLs to separate class (and parse like every other URL) Parsing 'data:' URLs took it's own route. It never set standard URL fields like path, query or fragment (except for scheme) and instead gave us separate methods called `data_payload()`, `data_mime_type()`, and `data_payload_is_base64()`. Because parsing 'data:' didn't use standard fields, running the following JS code: new URL('#a', 'data:text/plain,hello').toString() not only cleared the path as URLParser doesn't check for data from data_payload() function (making the result be 'data:#a'), but it also crashes the program because we forbid having an empty MIME type when we serialize to string. With this change, 'data:' URLs will be parsed like every other URLs. To decode the 'data:' URL contents, one needs to call process_data_url() on a URL, which will return a struct containing MIME type with already decoded data! :^) --- AK/URL.cpp | 128 +++++++++++++----- AK/URL.h | 24 +--- AK/URLParser.cpp | 43 ------ AK/URLParser.h | 3 - Tests/AK/TestURL.cpp | 83 +++++++----- .../Applications/Spreadsheet/HelpWindow.cpp | 4 +- .../LibWeb/Fetch/Fetching/Fetching.cpp | 14 +- .../LibWeb/HTML/HTMLCanvasElement.cpp | 2 +- .../LibWeb/Loader/ResourceLoader.cpp | 36 ++--- 9 files changed, 172 insertions(+), 165 deletions(-) diff --git a/AK/URL.cpp b/AK/URL.cpp index 06e21ae4b2b..d41746f6fe2 100644 --- a/AK/URL.cpp +++ b/AK/URL.cpp @@ -5,6 +5,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -173,18 +174,7 @@ bool URL::compute_validity() const if (m_scheme.is_empty()) return false; - if (m_scheme == "data") { - if (m_data_mime_type.is_empty()) - return false; - if (m_data_payload_is_base64) { - if (m_data_payload.length() % 4 != 0) - return false; - for (auto character : m_data_payload) { - if (!is_ascii_alphanumeric(character) || character == '+' || character == '/' || character == '=') - return false; - } - } - } else if (m_cannot_be_a_base_url) { + if (m_cannot_be_a_base_url) { if (m_paths.size() != 1) return false; if (m_paths[0].is_empty()) @@ -275,6 +265,22 @@ URL URL::create_with_url_or_path(DeprecatedString const& url_or_path) return URL::create_with_file_scheme(path); } +URL URL::create_with_data(StringView mime_type, StringView payload, bool is_base64) +{ + URL url; + url.set_cannot_be_a_base_url(true); + url.set_scheme("data"sv); + + StringBuilder builder; + builder.append(mime_type); + if (is_base64) + builder.append(";base64"sv); + builder.append(','); + builder.append(payload); + url.set_paths({ builder.to_deprecated_string() }); + return url; +} + // https://url.spec.whatwg.org/#special-scheme bool URL::is_special_scheme(StringView scheme) { @@ -293,30 +299,9 @@ DeprecatedString URL::serialize_path(ApplyPercentDecoding apply_percent_decoding return builder.to_deprecated_string(); } -DeprecatedString URL::serialize_data_url() const -{ - VERIFY(m_scheme == "data"); - VERIFY(!m_data_mime_type.is_null()); - VERIFY(!m_data_payload.is_null()); - StringBuilder builder; - builder.append(m_scheme); - builder.append(':'); - builder.append(m_data_mime_type); - if (m_data_payload_is_base64) - builder.append(";base64"sv); - builder.append(','); - // NOTE: The specification does not say anything about encoding this, but we should encode at least control and non-ASCII - // characters (since this is also a valid representation of the same data URL). - builder.append(URL::percent_encode(m_data_payload, PercentEncodeSet::C0Control)); - return builder.to_deprecated_string(); -} - // https://url.spec.whatwg.org/#concept-url-serializer DeprecatedString URL::serialize(ExcludeFragment exclude_fragment) const { - if (m_scheme == "data") - return serialize_data_url(); - // 1. Let output be url’s scheme and U+003A (:) concatenated. StringBuilder output; output.append(m_scheme); @@ -387,8 +372,7 @@ DeprecatedString URL::serialize(ExcludeFragment exclude_fragment) const DeprecatedString URL::serialize_for_display() const { VERIFY(m_valid); - if (m_scheme == "data") - return serialize_data_url(); + StringBuilder builder; builder.append(m_scheme); builder.append(':'); @@ -466,6 +450,80 @@ bool URL::equals(URL const& other, ExcludeFragment exclude_fragments) const return serialize(exclude_fragments) == other.serialize(exclude_fragments); } +// https://fetch.spec.whatwg.org/#data-url-processor +ErrorOr URL::process_data_url() const +{ + // 1. Assert: dataURL’s scheme is "data". + VERIFY(scheme() == "data"); + + // 2. Let input be the result of running the URL serializer on dataURL with exclude fragment set to true. + auto input = serialize(URL::ExcludeFragment::Yes); + + // 3. Remove the leading "data:" from input. + input = input.substring("data:"sv.length()); + + // 4. Let position point at the start of input. + + // 5. Let mimeType be the result of collecting a sequence of code points that are not equal to U+002C (,), given position. + auto position = input.find(','); + auto mime_type = input.substring_view(0, position.value_or(input.length())); + + // 6. Strip leading and trailing ASCII whitespace from mimeType. + mime_type = mime_type.trim_whitespace(TrimMode::Both); + + // 7. If position is past the end of input, then return failure. + if (!position.has_value()) + return Error::from_string_literal("Missing a comma character"); + + // 8. Advance position by 1. + position = position.value() + 1; + + // 9. Let encodedBody be the remainder of input. + auto encoded_body = input.substring_view(position.value()); + + // 10. Let body be the percent-decoding of encodedBody. + auto body = URL::percent_decode(encoded_body).to_byte_buffer(); + + // 11. If mimeType ends with U+003B (;), followed by zero or more U+0020 SPACE, followed by an ASCII case-insensitive match for "base64", then: + if (mime_type.ends_with("base64"sv, CaseSensitivity::CaseInsensitive)) { + auto trimmed_substring_view = mime_type.substring_view(0, mime_type.length() - 6); + trimmed_substring_view = trimmed_substring_view.trim(" "sv, TrimMode::Right); + if (trimmed_substring_view.ends_with(';')) { + // 1. Let stringBody be the isomorphic decode of body. + auto string_body = StringView(body); + + // 2. Set body to the forgiving-base64 decode of stringBody. + // FIXME: Check if it's really forgiving. + // 3. If body is failure, then return failure. + body = TRY(decode_base64(string_body)); + + // 4. Remove the last 6 code points from mimeType. + // 5. Remove trailing U+0020 SPACE code points from mimeType, if any. + // 6. Remove the last U+003B (;) from mimeType. + mime_type = trimmed_substring_view.substring_view(0, trimmed_substring_view.length() - 1); + } + } + + // 12. If mimeType starts with ";", then prepend "text/plain" to mimeType. + StringBuilder builder; + if (mime_type.starts_with(';')) { + builder.append("text/plain"sv); + builder.append(mime_type); + mime_type = builder.string_view(); + } + + // FIXME: Parse the MIME type's components according to https://mimesniff.spec.whatwg.org/#parse-a-mime-type + // FIXME: 13. Let mimeTypeRecord be the result of parsing mimeType. + auto mime_type_record = mime_type.trim("\n\r\t "sv, TrimMode::Both); + + // 14. If mimeTypeRecord is failure, then set mimeTypeRecord to text/plain;charset=US-ASCII. + if (mime_type_record.is_empty()) + mime_type_record = "text/plain;charset=US-ASCII"sv; + + // 15. Return a new data: URL struct whose MIME type is mimeTypeRecord and body is body. + return URL::DataURL { TRY(String::from_utf8(mime_type_record)), body }; +} + void URL::append_percent_encoded(StringBuilder& builder, u32 code_point) { if (code_point <= 0x7f) diff --git a/AK/URL.h b/AK/URL.h index 12f6d646afa..56729ab883d 100644 --- a/AK/URL.h +++ b/AK/URL.h @@ -128,14 +128,16 @@ public: URL complete_url(StringView) const; - bool data_payload_is_base64() const { return m_data_payload_is_base64; } - DeprecatedString const& data_mime_type() const { return m_data_mime_type; } - DeprecatedString const& data_payload() const { return m_data_payload; } + struct DataURL { + String mime_type; + ByteBuffer body; + }; + ErrorOr process_data_url() const; static URL create_with_url_or_path(DeprecatedString const&); static URL create_with_file_scheme(DeprecatedString const& path, DeprecatedString const& fragment = {}, DeprecatedString const& hostname = {}); static URL create_with_help_scheme(DeprecatedString const& path, DeprecatedString const& fragment = {}, DeprecatedString const& hostname = {}); - static URL create_with_data(DeprecatedString mime_type, DeprecatedString payload, bool is_base64 = false) { return URL(move(mime_type), move(payload), is_base64); } + static URL create_with_data(StringView mime_type, StringView payload, bool is_base64 = false); static u16 default_port_for_scheme(StringView); static bool is_special_scheme(StringView); @@ -152,17 +154,7 @@ public: static bool code_point_is_in_percent_encode_set(u32 code_point, URL::PercentEncodeSet); private: - URL(DeprecatedString&& data_mime_type, DeprecatedString&& data_payload, bool payload_is_base64) - : m_valid(true) - , m_scheme("data") - , m_data_payload_is_base64(payload_is_base64) - , m_data_mime_type(move(data_mime_type)) - , m_data_payload(move(data_payload)) - { - } - bool compute_validity() const; - DeprecatedString serialize_data_url() const; static void append_percent_encoded_if_necessary(StringBuilder&, u32 code_point, PercentEncodeSet set = PercentEncodeSet::Userinfo); static void append_percent_encoded(StringBuilder&, u32 code_point); @@ -196,10 +188,6 @@ private: DeprecatedString m_fragment; bool m_cannot_be_a_base_url { false }; - - bool m_data_payload_is_base64 { false }; - DeprecatedString m_data_mime_type; - DeprecatedString m_data_payload; }; template<> diff --git a/AK/URLParser.cpp b/AK/URLParser.cpp index e890c4a29b3..ef0d2245f98 100644 --- a/AK/URLParser.cpp +++ b/AK/URLParser.cpp @@ -697,42 +697,6 @@ DeprecatedString URLParser::percent_encode_after_encoding(StringView input, URL: return output.to_deprecated_string(); } -// https://fetch.spec.whatwg.org/#data-urls -// FIXME: This only loosely follows the spec, as we use the same class for "regular" and data URLs, unlike the spec. -Optional URLParser::parse_data_url(StringView raw_input) -{ - dbgln_if(URL_PARSER_DEBUG, "URLParser::parse_data_url: Parsing '{}'.", raw_input); - VERIFY(raw_input.starts_with("data:"sv)); - auto input = raw_input.substring_view(5); - auto comma_offset = input.find(','); - if (!comma_offset.has_value()) - return {}; - auto mime_type = StringUtils::trim(input.substring_view(0, comma_offset.value()), "\t\n\f\r "sv, TrimMode::Both); - auto encoded_body = input.substring_view(comma_offset.value() + 1); - auto body = URL::percent_decode(encoded_body); - bool is_base64_encoded = false; - if (mime_type.ends_with("base64"sv, CaseSensitivity::CaseInsensitive)) { - auto substring_view = mime_type.substring_view(0, mime_type.length() - 6); - auto trimmed_substring_view = StringUtils::trim(substring_view, " "sv, TrimMode::Right); - if (trimmed_substring_view.ends_with(';')) { - is_base64_encoded = true; - mime_type = trimmed_substring_view.substring_view(0, trimmed_substring_view.length() - 1); - } - } - - StringBuilder builder; - if (mime_type.starts_with(";"sv) || mime_type.is_empty()) { - builder.append("text/plain"sv); - builder.append(mime_type); - mime_type = builder.string_view(); - } - - // FIXME: Parse the MIME type's components according to https://mimesniff.spec.whatwg.org/#parse-a-mime-type - URL url { StringUtils::trim(mime_type, "\n\r\t "sv, TrimMode::Both), move(body), is_base64_encoded }; - dbgln_if(URL_PARSER_DEBUG, "URLParser::parse_data_url: Parsed data URL to be '{}'.", url.serialize()); - return url; -} - // https://url.spec.whatwg.org/#concept-basic-url-parser // NOTE: This parser assumes a UTF-8 encoding. // NOTE: Refrain from using the URL classes setters inside this algorithm. Rather, set the values directly. This bypasses the setters' built-in @@ -746,13 +710,6 @@ URL URLParser::basic_parse(StringView raw_input, Optional const& base_url, if (raw_input.is_empty()) return base_url.has_value() ? *base_url : URL {}; - if (raw_input.starts_with("data:"sv)) { - auto maybe_url = parse_data_url(raw_input); - if (!maybe_url.has_value()) - return {}; - return maybe_url.release_value(); - } - size_t start_index = 0; size_t end_index = raw_input.length(); diff --git a/AK/URLParser.h b/AK/URLParser.h index f506c535f4a..31149d0aaa6 100644 --- a/AK/URLParser.h +++ b/AK/URLParser.h @@ -63,9 +63,6 @@ public: // https://url.spec.whatwg.org/#concept-host-serializer static ErrorOr serialize_host(URL::Host const&); - -private: - static Optional parse_data_url(StringView raw_input); }; #undef ENUMERATE_STATES diff --git a/Tests/AK/TestURL.cpp b/Tests/AK/TestURL.cpp index 08648afab29..5a391c99ea2 100644 --- a/Tests/AK/TestURL.cpp +++ b/Tests/AK/TestURL.cpp @@ -7,7 +7,6 @@ #include -#include #include #include @@ -111,7 +110,6 @@ TEST_CASE(some_bad_urls) EXPECT_EQ(URL("http://serenityos.org:abc"sv).is_valid(), false); EXPECT_EQ(URL("http://serenityos.org:abc:80"sv).is_valid(), false); EXPECT_EQ(URL("http://serenityos.org:abc:80/"sv).is_valid(), false); - EXPECT_EQ(URL("data:"sv).is_valid(), false); } TEST_CASE(serialization) @@ -246,10 +244,11 @@ TEST_CASE(data_url) EXPECT(url.is_valid()); EXPECT_EQ(url.scheme(), "data"); EXPECT(url.host().has()); - EXPECT_EQ(url.data_mime_type(), "text/html"); - EXPECT_EQ(url.data_payload(), "test"); - EXPECT(!url.data_payload_is_base64()); EXPECT_EQ(url.serialize(), "data:text/html,test"); + + auto data_url = TRY_OR_FAIL(url.process_data_url()); + EXPECT_EQ(data_url.mime_type, "text/html"); + EXPECT_EQ(StringView(data_url.body.bytes()), "test"sv); } TEST_CASE(data_url_default_mime_type) @@ -258,10 +257,11 @@ TEST_CASE(data_url_default_mime_type) EXPECT(url.is_valid()); EXPECT_EQ(url.scheme(), "data"); EXPECT(url.host().has()); - EXPECT_EQ(url.data_mime_type(), "text/plain"); - EXPECT_EQ(url.data_payload(), "test"); - EXPECT(!url.data_payload_is_base64()); - EXPECT_EQ(url.serialize(), "data:text/plain,test"); + EXPECT_EQ(url.serialize(), "data:,test"); + + auto data_url = TRY_OR_FAIL(url.process_data_url()); + EXPECT_EQ(data_url.mime_type, "text/plain;charset=US-ASCII"); + EXPECT_EQ(StringView(data_url.body.bytes()), "test"sv); } TEST_CASE(data_url_encoded) @@ -270,46 +270,50 @@ TEST_CASE(data_url_encoded) EXPECT(url.is_valid()); EXPECT_EQ(url.scheme(), "data"); EXPECT(url.host().has()); - EXPECT_EQ(url.data_mime_type(), "text/html"); - EXPECT_EQ(url.data_payload(), "Hello friends,%0X%X0"); - EXPECT(!url.data_payload_is_base64()); - EXPECT_EQ(url.serialize(), "data:text/html,Hello friends,%0X%X0"); + EXPECT_EQ(url.serialize(), "data:text/html,Hello%20friends%2C%0X%X0"); + + auto data_url = TRY_OR_FAIL(url.process_data_url()); + EXPECT_EQ(data_url.mime_type, "text/html"); + EXPECT_EQ(StringView(data_url.body.bytes()), "Hello friends,%0X%X0"sv); } TEST_CASE(data_url_base64_encoded) { - URL url("data:text/html;base64,test"sv); + URL url("data:text/html;base64,dGVzdA=="sv); EXPECT(url.is_valid()); EXPECT_EQ(url.scheme(), "data"); EXPECT(url.host().has()); - EXPECT_EQ(url.data_mime_type(), "text/html"); - EXPECT_EQ(url.data_payload(), "test"); - EXPECT(url.data_payload_is_base64()); - EXPECT_EQ(url.serialize(), "data:text/html;base64,test"); + EXPECT_EQ(url.serialize(), "data:text/html;base64,dGVzdA=="); + + auto data_url = TRY_OR_FAIL(url.process_data_url()); + EXPECT_EQ(data_url.mime_type, "text/html"); + EXPECT_EQ(StringView(data_url.body.bytes()), "test"sv); } TEST_CASE(data_url_base64_encoded_default_mime_type) { - URL url("data:;base64,test"sv); + URL url("data:;base64,dGVzdA=="sv); EXPECT(url.is_valid()); EXPECT_EQ(url.scheme(), "data"); EXPECT(url.host().has()); - EXPECT_EQ(url.data_mime_type(), "text/plain"); - EXPECT_EQ(url.data_payload(), "test"); - EXPECT(url.data_payload_is_base64()); - EXPECT_EQ(url.serialize(), "data:text/plain;base64,test"); + EXPECT_EQ(url.serialize(), "data:;base64,dGVzdA=="); + + auto data_url = TRY_OR_FAIL(url.process_data_url()); + EXPECT_EQ(data_url.mime_type, "text/plain;charset=US-ASCII"); + EXPECT_EQ(StringView(data_url.body.bytes()), "test"sv); } TEST_CASE(data_url_base64_encoded_with_whitespace) { - URL url("data: text/html ; bAsE64 , test with whitespace "sv); + URL url("data: text/html ; bAsE64 , dGVz dA== "sv); EXPECT(url.is_valid()); EXPECT_EQ(url.scheme(), "data"); EXPECT(url.host().has()); - EXPECT_EQ(url.data_mime_type(), "text/html"); - EXPECT_EQ(url.data_payload(), " test with whitespace "); - EXPECT(url.data_payload_is_base64()); - EXPECT_EQ(url.serialize(), "data:text/html;base64, test with whitespace "); + EXPECT_EQ(url.serialize(), "data: text/html ; bAsE64 , dGVz dA=="); + + auto data_url = TRY_OR_FAIL(url.process_data_url()); + EXPECT_EQ(data_url.mime_type, "text/html"); + EXPECT_EQ(StringView(data_url.body.bytes()), "test"); } TEST_CASE(data_url_base64_encoded_with_inline_whitespace) @@ -318,12 +322,23 @@ TEST_CASE(data_url_base64_encoded_with_inline_whitespace) EXPECT(url.is_valid()); EXPECT_EQ(url.scheme(), "data"); EXPECT(url.host().has()); - EXPECT_EQ(url.data_mime_type(), "text/javascript"); - EXPECT(url.data_payload_is_base64()); - EXPECT_EQ(url.data_payload(), " ZD Qg\r\nPS An Zm91cic\r\n 7 "sv); - auto decode_result = decode_base64(url.data_payload()); - EXPECT_EQ(decode_result.is_error(), false); - EXPECT_EQ(StringView(decode_result.value()), "d4 = 'four';"sv); + + auto data_url = TRY_OR_FAIL(url.process_data_url()); + EXPECT_EQ(data_url.mime_type, "text/javascript"); + EXPECT_EQ(StringView(data_url.body.bytes()), "d4 = 'four';"sv); +} + +TEST_CASE(data_url_completed_with_fragment) +{ + auto url = URL("data:text/plain,test"sv).complete_url("#a"sv); + EXPECT(url.is_valid()); + EXPECT_EQ(url.scheme(), "data"); + EXPECT_EQ(url.fragment(), "a"); + EXPECT(url.host().has()); + + auto data_url = TRY_OR_FAIL(url.process_data_url()); + EXPECT_EQ(data_url.mime_type, "text/plain"); + EXPECT_EQ(StringView(data_url.body.bytes()), "test"sv); } TEST_CASE(trailing_slash_with_complete_url) diff --git a/Userland/Applications/Spreadsheet/HelpWindow.cpp b/Userland/Applications/Spreadsheet/HelpWindow.cpp index 845af963606..013b15569a0 100644 --- a/Userland/Applications/Spreadsheet/HelpWindow.cpp +++ b/Userland/Applications/Spreadsheet/HelpWindow.cpp @@ -124,7 +124,7 @@ HelpWindow::HelpWindow(GUI::Window* parent) window->show(); } else if (url.host() == String::from_utf8_short_string("doc"sv)) { auto entry = LexicalPath::basename(url.serialize_path()); - m_webview->load(URL::create_with_data("text/html", render(entry))); + m_webview->load(URL::create_with_data("text/html"sv, render(entry))); } else { dbgln("Invalid spreadsheet action domain '{}'", url.serialized_host().release_value_but_fixme_should_propagate_errors()); } @@ -135,7 +135,7 @@ HelpWindow::HelpWindow(GUI::Window* parent) return; auto key = static_cast(m_listview->model())->key(index); - m_webview->load(URL::create_with_data("text/html", render(key))); + m_webview->load(URL::create_with_data("text/html"sv, render(key))); }; } diff --git a/Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp b/Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp index b846ca21b47..700e123f20e 100644 --- a/Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp +++ b/Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp @@ -714,17 +714,15 @@ WebIDL::ExceptionOr> scheme_fetch(JS::Realm& r // -> "data" else if (request->current_url().scheme() == "data"sv) { // 1. Let dataURLStruct be the result of running the data: URL processor on request’s current URL. - auto const& url = request->current_url(); - auto data_or_error = url.data_payload_is_base64() - ? decode_base64(url.data_payload()) - : TRY_OR_THROW_OOM(vm, ByteBuffer::copy(url.data_payload().bytes())); + auto data_url_struct = request->current_url().process_data_url(); // 2. If dataURLStruct is failure, then return a network error. - if (data_or_error.is_error()) - return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request has invalid base64 'data:' URL"sv)); + if (data_url_struct.is_error()) + return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Failed to process 'data:' URL"sv)); // 3. Let mimeType be dataURLStruct’s MIME type, serialized. - auto const& mime_type = url.data_mime_type(); + // FIXME: Serialize MIME type. + auto const& mime_type = data_url_struct.value().mime_type; // 4. Return a new response whose status message is `OK`, header list is « (`Content-Type`, mimeType) », and // body is dataURLStruct’s body as a body. @@ -732,7 +730,7 @@ WebIDL::ExceptionOr> scheme_fetch(JS::Realm& r response->set_status_message(MUST(ByteBuffer::copy("OK"sv.bytes()))); auto header = TRY_OR_THROW_OOM(vm, Infrastructure::Header::from_string_pair("Content-Type"sv, mime_type)); TRY_OR_THROW_OOM(vm, response->header_list()->append(move(header))); - response->set_body(TRY(Infrastructure::byte_sequence_as_body(realm, data_or_error.value().span()))); + response->set_body(TRY(Infrastructure::byte_sequence_as_body(realm, data_url_struct.value().body))); return PendingResponse::create(vm, request, response); } // -> "file" diff --git a/Userland/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp index e2636a7c48d..5bd2358eaca 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp @@ -195,7 +195,7 @@ DeprecatedString HTMLCanvasElement::to_data_url(DeprecatedString const& type, [[ // FIXME: propagate error return {}; } - return AK::URL::create_with_data(type, base64_encoded_or_error.release_value().to_deprecated_string(), true).to_deprecated_string(); + return AK::URL::create_with_data(type, base64_encoded_or_error.release_value(), true).to_deprecated_string(); } void HTMLCanvasElement::present() diff --git a/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp b/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp index cd831550847..9bdfcfa6ae5 100644 --- a/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp +++ b/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp @@ -5,7 +5,6 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include #include #include #include @@ -123,7 +122,7 @@ RefPtr ResourceLoader::load_resource(Resource::Type type, LoadRequest& static DeprecatedString sanitized_url_for_logging(AK::URL const& url) { if (url.scheme() == "data"sv) - return DeprecatedString::formatted("[data URL, mime-type={}, size={}]", url.data_mime_type(), url.data_payload().length()); + return "[data URL]"sv; return url.to_deprecated_string(); } @@ -204,30 +203,25 @@ void ResourceLoader::load(LoadRequest& request, Function response_headers; - response_headers.set("Content-Type", url.data_mime_type()); + response_headers.set("Content-Type", data_url.mime_type.to_deprecated_string()); log_success(request); - Platform::EventLoopPlugin::the().deferred_invoke([data = move(data), response_headers = move(response_headers), success_callback = move(success_callback)] { + + Platform::EventLoopPlugin::the().deferred_invoke([data = move(data_url.body), response_headers = move(response_headers), success_callback = move(success_callback)] { success_callback(data, response_headers, {}); }); return;