From ea15501f37533a6e8c55bbc9cd578924d8cadd05 Mon Sep 17 00:00:00 2001 From: Kemal Zebari Date: Thu, 30 Nov 2023 12:44:27 -0800 Subject: [PATCH] LibWeb/MimeSniff: Add sniffing in a browsing context --- Tests/LibWeb/TestMimeSniff.cpp | 8 +++++++- Userland/Libraries/LibWeb/MimeSniff/Resource.cpp | 16 +++++++++++++++- Userland/Libraries/LibWeb/MimeSniff/Resource.h | 7 +++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/Tests/LibWeb/TestMimeSniff.cpp b/Tests/LibWeb/TestMimeSniff.cpp index 49572bce34..e269e9dbf8 100644 --- a/Tests/LibWeb/TestMimeSniff.cpp +++ b/Tests/LibWeb/TestMimeSniff.cpp @@ -31,7 +31,7 @@ TEST_CASE(determine_computed_mime_type_given_no_sniff_is_unset) EXPECT_EQ(xml_mime_type, MUST(computed_mime_type.serialized())); } -TEST_CASE(compute_unknown_mime_type) +TEST_CASE(determine_computed_mime_type_in_both_none_and_browsing_sniffing_context) { HashMap> mime_type_to_headers_map; @@ -84,8 +84,14 @@ TEST_CASE(compute_unknown_mime_type) auto mime_type = mime_type_to_headers.key; for (auto const& header : mime_type_to_headers.value) { + + // Test in a non-specific sniffing context. auto computed_mime_type = MUST(Web::MimeSniff::Resource::sniff(header.bytes())); EXPECT_EQ(mime_type, computed_mime_type.essence()); + + // Test sniffing in a browsing context. + computed_mime_type = MUST(Web::MimeSniff::Resource::sniff(header.bytes(), Web::MimeSniff::SniffingConfiguration { .sniffing_context = Web::MimeSniff::SniffingContext::Browsing })); + EXPECT_EQ(mime_type, computed_mime_type.essence()); } } } diff --git a/Userland/Libraries/LibWeb/MimeSniff/Resource.cpp b/Userland/Libraries/LibWeb/MimeSniff/Resource.cpp index d578bcd565..c6a194db88 100644 --- a/Userland/Libraries/LibWeb/MimeSniff/Resource.cpp +++ b/Userland/Libraries/LibWeb/MimeSniff/Resource.cpp @@ -370,7 +370,7 @@ ErrorOr Resource::create(ReadonlyBytes data, SniffingConfiguration con auto resource = Resource { data, configuration.no_sniff, move(default_computed_mime_type) }; TRY(resource.supplied_mime_type_detection_algorithm(configuration.scheme, move(configuration.supplied_type))); - TRY(resource.mime_type_sniffing_algorithm()); + TRY(resource.context_specific_sniffing_algorithm(configuration.sniffing_context)); return resource; } @@ -520,4 +520,18 @@ ErrorOr Resource::mime_type_sniffing_algorithm() return {}; } +// https://mimesniff.spec.whatwg.org/#context-specific-sniffing-algorithm +ErrorOr Resource::context_specific_sniffing_algorithm(SniffingContext sniffing_context) +{ + // A context-specific sniffing algorithm determines the computed MIME type of a resource only if + // the resource is a MIME type relevant to a particular context. + if (sniffing_context == SniffingContext::None || sniffing_context == SniffingContext::Browsing) { + // https://mimesniff.spec.whatwg.org/#sniffing-in-a-browsing-context + // Use the MIME type sniffing algorithm. + return mime_type_sniffing_algorithm(); + } + + return {}; +} + } diff --git a/Userland/Libraries/LibWeb/MimeSniff/Resource.h b/Userland/Libraries/LibWeb/MimeSniff/Resource.h index d1b90192b2..c3499f6da2 100644 --- a/Userland/Libraries/LibWeb/MimeSniff/Resource.h +++ b/Userland/Libraries/LibWeb/MimeSniff/Resource.h @@ -10,7 +10,13 @@ namespace Web::MimeSniff { +enum class SniffingContext { + None, + Browsing +}; + struct SniffingConfiguration { + SniffingContext sniffing_context { SniffingContext::None }; StringView scheme { ""sv }; Optional supplied_type = {}; bool no_sniff { false }; @@ -33,6 +39,7 @@ private: void read_the_resource_header(ReadonlyBytes data); ErrorOr supplied_mime_type_detection_algorithm(StringView scheme, Optional supplied_type); ErrorOr mime_type_sniffing_algorithm(); + ErrorOr context_specific_sniffing_algorithm(SniffingContext sniffing_context); // https://mimesniff.spec.whatwg.org/#supplied-mime-type // A supplied MIME type, the MIME type determined by the supplied MIME type detection algorithm.