From 08a390430987f56cdb4f43a294a6f769d676e12b Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Sun, 19 May 2024 13:17:52 +0100 Subject: [PATCH] LibWeb/MimeSniff: Implement "minimize a supported MIME type" See: - https://github.com/whatwg/mimesniff/commit/227a469 --- Tests/LibWeb/TestMimeSniff.cpp | 34 +++++++++++++++++++ .../Libraries/LibWeb/MimeSniff/MimeType.cpp | 26 ++++++++++++++ .../Libraries/LibWeb/MimeSniff/MimeType.h | 2 ++ 3 files changed, 62 insertions(+) diff --git a/Tests/LibWeb/TestMimeSniff.cpp b/Tests/LibWeb/TestMimeSniff.cpp index 160254fbe05..c09a080df83 100644 --- a/Tests/LibWeb/TestMimeSniff.cpp +++ b/Tests/LibWeb/TestMimeSniff.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2023-2024, Kemal Zebari . + * Copyright (c) 2024, Jamie Mansfield * * SPDX-License-Identifier: BSD-2-Clause */ @@ -330,3 +331,36 @@ TEST_CASE(determine_computed_mime_type_given_text_or_binary_context) })); EXPECT_EQ("application/octet-stream"sv, MUST(computed_mime_type.serialized())); } + +TEST_CASE(determine_minimised_mime_type) +{ + HashMap mime_type_to_minimised_mime_type_map; + + // JavaScript MIME types should always be "text/javascript". + mime_type_to_minimised_mime_type_map.set("text/javascript"sv, "text/javascript"sv); + mime_type_to_minimised_mime_type_map.set("application/javascript"sv, "text/javascript"sv); + mime_type_to_minimised_mime_type_map.set("text/javascript; charset=utf-8"sv, "text/javascript"sv); + + // JSON MIME types should always be "application/json". + mime_type_to_minimised_mime_type_map.set("application/json"sv, "application/json"sv); + mime_type_to_minimised_mime_type_map.set("text/json"sv, "application/json"sv); + mime_type_to_minimised_mime_type_map.set("application/json; charset=utf-8"sv, "application/json"sv); + + // SVG MIME types should always be "image/svg+xml". + mime_type_to_minimised_mime_type_map.set("image/svg+xml"sv, "image/svg+xml"sv); + mime_type_to_minimised_mime_type_map.set("image/svg+xml; charset=utf-8"sv, "image/svg+xml"sv); + + // XML MIME types should always be "application/xml". + mime_type_to_minimised_mime_type_map.set("application/xml"sv, "application/xml"sv); + mime_type_to_minimised_mime_type_map.set("text/xml"sv, "application/xml"sv); + mime_type_to_minimised_mime_type_map.set("application/xml; charset=utf-8"sv, "application/xml"sv); + + // MIME types not supported by the user-agent should return an empty string. + mime_type_to_minimised_mime_type_map.set("application/java-archive"sv, ""sv); + mime_type_to_minimised_mime_type_map.set("application/zip"sv, ""sv); + + for (auto const& mime_type_to_minimised_mime_type : mime_type_to_minimised_mime_type_map) { + auto mime_type = MUST(Web::MimeSniff::MimeType::parse(mime_type_to_minimised_mime_type.key)).release_value(); + EXPECT_EQ(mime_type_to_minimised_mime_type.value, Web::MimeSniff::minimise_a_supported_mime_type(mime_type)); + } +} diff --git a/Userland/Libraries/LibWeb/MimeSniff/MimeType.cpp b/Userland/Libraries/LibWeb/MimeSniff/MimeType.cpp index 0cfd663ad5b..11cad3bb2cd 100644 --- a/Userland/Libraries/LibWeb/MimeSniff/MimeType.cpp +++ b/Userland/Libraries/LibWeb/MimeSniff/MimeType.cpp @@ -2,6 +2,7 @@ * Copyright (c) 2022, Luke Wilde * Copyright (c) 2022-2023, Linus Groh * Copyright (c) 2022, networkException + * Copyright (c) 2024, Jamie Mansfield * * SPDX-License-Identifier: BSD-2-Clause */ @@ -369,4 +370,29 @@ bool MimeType::is_json() const return subtype().ends_with_bytes("+json"sv) || essence().is_one_of("application/json"sv, "text/json"sv); } +// https://mimesniff.spec.whatwg.org/#minimize-a-supported-mime-type +String minimise_a_supported_mime_type(MimeType const& mime_type) +{ + // 1. If mimeType is a JavaScript MIME type, then return "text/javascript". + if (mime_type.is_javascript()) + return "text/javascript"_string; + + // 2. If mimeType is a JSON MIME type, then return "application/json". + if (mime_type.is_json()) + return "application/json"_string; + + // 3. If mimeType’s essence is "image/svg+xml", then return "image/svg+xml". + if (mime_type.essence() == "image/svg+xml") + return "image/svg+xml"_string; + + // 4. If mimeType is an XML MIME type, then return "application/xml". + if (mime_type.is_xml()) + return "application/xml"_string; + + // FIXME: 5. If mimeType is supported by the user agent, then return mimeType’s essence. + + // 6. Return the empty string. + return {}; +} + } diff --git a/Userland/Libraries/LibWeb/MimeSniff/MimeType.h b/Userland/Libraries/LibWeb/MimeSniff/MimeType.h index d914616a856..40695cf6f1d 100644 --- a/Userland/Libraries/LibWeb/MimeSniff/MimeType.h +++ b/Userland/Libraries/LibWeb/MimeSniff/MimeType.h @@ -67,4 +67,6 @@ private: String m_cached_essence; }; +String minimise_a_supported_mime_type(MimeType const&); + }