mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-22 17:31:58 -05:00
LibWeb: Make MimeSniff::MimeType::parse() infallible
It already returns an empty Optional for failures, so there's no need to wrap it in an ErrorOr as well. (cherry picked from commit 5c20bc2afc23b04ccd8037d414592e4ee841a053; amended to fix conflict in StyleComputer.cpp due to serenity not having the third commit of LadybirdBrowser/ladybird#1278)
This commit is contained in:
parent
d8c9ff6c09
commit
cf0516b616
14 changed files with 38 additions and 36 deletions
|
@ -38,7 +38,7 @@ TEST_CASE(determine_computed_mime_type_given_no_sniff_is_unset)
|
|||
TEST_CASE(determine_computed_mime_type_given_xml_mime_type_as_supplied_type)
|
||||
{
|
||||
auto xml_mime_type = "application/rss+xml"sv;
|
||||
auto supplied_type = MUST(Web::MimeSniff::MimeType::parse(xml_mime_type)).release_value();
|
||||
auto supplied_type = Web::MimeSniff::MimeType::parse(xml_mime_type).release_value();
|
||||
auto computed_mime_type = MUST(Web::MimeSniff::Resource::sniff("\x00"sv.bytes(), Web::MimeSniff::SniffingConfiguration { .supplied_type = supplied_type }));
|
||||
|
||||
EXPECT_EQ(xml_mime_type, computed_mime_type.serialized());
|
||||
|
@ -85,7 +85,7 @@ TEST_CASE(determine_computed_mime_type_given_supplied_type_that_is_an_apache_bug
|
|||
|
||||
// Cover all Apache bug MIME types.
|
||||
for (auto const& apache_bug_mime_type : apache_bug_mime_types) {
|
||||
auto supplied_type = MUST(Web::MimeSniff::MimeType::parse(apache_bug_mime_type)).release_value();
|
||||
auto supplied_type = Web::MimeSniff::MimeType::parse(apache_bug_mime_type).release_value();
|
||||
auto computed_mime_type = MUST(Web::MimeSniff::Resource::sniff("Hello world!"sv.bytes(),
|
||||
Web::MimeSniff::SniffingConfiguration { .scheme = "http"sv, .supplied_type = supplied_type }));
|
||||
|
||||
|
@ -195,7 +195,7 @@ TEST_CASE(determine_computed_mime_type_in_image_sniffing_context)
|
|||
{
|
||||
// Cover case where supplied type is an XML MIME type.
|
||||
auto mime_type = "application/rss+xml"sv;
|
||||
auto supplied_type = MUST(Web::MimeSniff::MimeType::parse(mime_type)).release_value();
|
||||
auto supplied_type = Web::MimeSniff::MimeType::parse(mime_type).release_value();
|
||||
auto computed_mime_type = MUST(Web::MimeSniff::Resource::sniff(""sv.bytes(), Web::MimeSniff::SniffingConfiguration { .sniffing_context = Web::MimeSniff::SniffingContext::Image, .supplied_type = supplied_type }));
|
||||
|
||||
EXPECT_EQ(mime_type, computed_mime_type.serialized());
|
||||
|
@ -218,7 +218,7 @@ TEST_CASE(determine_computed_mime_type_in_image_sniffing_context)
|
|||
|
||||
// Cover case where we aren't dealing with an image MIME type.
|
||||
mime_type = "text/html"sv;
|
||||
supplied_type = MUST(Web::MimeSniff::MimeType::parse("text/html"sv)).release_value();
|
||||
supplied_type = Web::MimeSniff::MimeType::parse("text/html"sv).release_value();
|
||||
computed_mime_type = MUST(Web::MimeSniff::Resource::sniff(""sv.bytes(), Web::MimeSniff::SniffingConfiguration { .sniffing_context = Web::MimeSniff::SniffingContext::Image, .supplied_type = supplied_type }));
|
||||
|
||||
EXPECT_EQ(mime_type, computed_mime_type.essence());
|
||||
|
@ -228,7 +228,7 @@ TEST_CASE(determine_computed_mime_type_in_audio_or_video_sniffing_context)
|
|||
{
|
||||
// Cover case where supplied type is an XML MIME type.
|
||||
auto mime_type = "application/rss+xml"sv;
|
||||
auto supplied_type = MUST(Web::MimeSniff::MimeType::parse(mime_type)).release_value();
|
||||
auto supplied_type = Web::MimeSniff::MimeType::parse(mime_type).release_value();
|
||||
auto computed_mime_type = MUST(Web::MimeSniff::Resource::sniff(""sv.bytes(), Web::MimeSniff::SniffingConfiguration {
|
||||
.sniffing_context = Web::MimeSniff::SniffingContext::AudioOrVideo,
|
||||
.supplied_type = supplied_type,
|
||||
|
@ -253,7 +253,7 @@ TEST_CASE(determine_computed_mime_type_in_audio_or_video_sniffing_context)
|
|||
|
||||
// Cover case where we aren't dealing with an audio or video MIME type.
|
||||
mime_type = "text/html"sv;
|
||||
supplied_type = MUST(Web::MimeSniff::MimeType::parse("text/html"sv)).release_value();
|
||||
supplied_type = Web::MimeSniff::MimeType::parse("text/html"sv).release_value();
|
||||
computed_mime_type = MUST(Web::MimeSniff::Resource::sniff(""sv.bytes(), Web::MimeSniff::SniffingConfiguration {
|
||||
.sniffing_context = Web::MimeSniff::SniffingContext::AudioOrVideo,
|
||||
.supplied_type = supplied_type,
|
||||
|
@ -299,7 +299,7 @@ TEST_CASE(determine_computed_mime_type_in_a_font_context)
|
|||
{
|
||||
// Cover case where supplied type is an XML MIME type.
|
||||
auto mime_type = "application/rss+xml"sv;
|
||||
auto supplied_type = MUST(Web::MimeSniff::MimeType::parse(mime_type)).release_value();
|
||||
auto supplied_type = Web::MimeSniff::MimeType::parse(mime_type).release_value();
|
||||
auto computed_mime_type = MUST(Web::MimeSniff::Resource::sniff(""sv.bytes(), Web::MimeSniff::SniffingConfiguration {
|
||||
.sniffing_context = Web::MimeSniff::SniffingContext::Font,
|
||||
.supplied_type = supplied_type,
|
||||
|
@ -327,7 +327,7 @@ TEST_CASE(determine_computed_mime_type_in_a_font_context)
|
|||
|
||||
// Cover case where we aren't dealing with a font MIME type.
|
||||
mime_type = "text/html"sv;
|
||||
supplied_type = MUST(Web::MimeSniff::MimeType::parse("text/html"sv)).release_value();
|
||||
supplied_type = Web::MimeSniff::MimeType::parse("text/html"sv).release_value();
|
||||
computed_mime_type = MUST(Web::MimeSniff::Resource::sniff(""sv.bytes(), Web::MimeSniff::SniffingConfiguration {
|
||||
.sniffing_context = Web::MimeSniff::SniffingContext::Font,
|
||||
.supplied_type = supplied_type,
|
||||
|
@ -374,7 +374,7 @@ TEST_CASE(determine_minimised_mime_type)
|
|||
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();
|
||||
auto mime_type = 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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ void Clipboard::initialize(JS::Realm& realm)
|
|||
static String os_specific_well_known_format(StringView mime_type_string)
|
||||
{
|
||||
// NOTE: Here we always takes the Linux case, and defer to the chrome layer to handle OS specific implementations.
|
||||
auto mime_type = MUST(MimeSniff::MimeType::parse(mime_type_string));
|
||||
auto mime_type = MimeSniff::MimeType::parse(mime_type_string);
|
||||
|
||||
// 1. Let wellKnownFormat be an empty string.
|
||||
String well_known_format {};
|
||||
|
|
|
@ -372,7 +372,7 @@ Optional<MimeSniff::MimeType> HeaderList::extract_mime_type() const
|
|||
// 6. For each value of values:
|
||||
for (auto const& value : *values) {
|
||||
// 1. Let temporaryMimeType be the result of parsing value.
|
||||
auto temporary_mime_type = MUST(MimeSniff::MimeType::parse(value));
|
||||
auto temporary_mime_type = MimeSniff::MimeType::parse(value);
|
||||
|
||||
// 2. If temporaryMimeType is failure or its essence is "*/*", then continue.
|
||||
if (!temporary_mime_type.has_value() || temporary_mime_type->essence() == "*/*"sv)
|
||||
|
@ -530,7 +530,7 @@ bool is_cors_safelisted_request_header(Header const& header)
|
|||
return false;
|
||||
|
||||
// 2. Let mimeType be the result of parsing the result of isomorphic decoding value.
|
||||
auto mime_type = MimeSniff::MimeType::parse(StringView { value }).release_value_but_fixme_should_propagate_errors();
|
||||
auto mime_type = MimeSniff::MimeType::parse(StringView { value });
|
||||
|
||||
// 3. If mimeType is failure, then return false.
|
||||
if (!mime_type.has_value())
|
||||
|
|
|
@ -97,7 +97,7 @@ ErrorOr<DataURL> process_data_url(URL::URL const& data_url)
|
|||
}
|
||||
|
||||
// 13. Let mimeTypeRecord be the result of parsing mimeType.
|
||||
auto mime_type_record = TRY(MimeSniff::MimeType::parse(mime_type));
|
||||
auto mime_type_record = MimeSniff::MimeType::parse(mime_type);
|
||||
|
||||
// 14. If mimeTypeRecord is failure, then set mimeTypeRecord to text/plain;charset=US-ASCII.
|
||||
if (!mime_type_record.has_value()) {
|
||||
|
|
|
@ -204,7 +204,7 @@ JS::NonnullGCPtr<Blob> Blob::create(JS::Realm& realm, Optional<Vector<BlobPart>>
|
|||
|
||||
// NOTE: The spec is out of date, and we are supposed to call into the MimeType parser here.
|
||||
if (!options->type.is_empty()) {
|
||||
auto maybe_parsed_type = MUST(Web::MimeSniff::MimeType::parse(options->type));
|
||||
auto maybe_parsed_type = Web::MimeSniff::MimeType::parse(options->type);
|
||||
|
||||
if (maybe_parsed_type.has_value())
|
||||
type = maybe_parsed_type->serialized();
|
||||
|
|
|
@ -62,7 +62,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<File>> File::create(JS::Realm& realm, Vecto
|
|||
// FIXME: 2. Convert every character in t to ASCII lowercase.
|
||||
|
||||
// NOTE: The spec is out of date, and we are supposed to call into the MimeType parser here.
|
||||
auto maybe_parsed_type = MUST(Web::MimeSniff::MimeType::parse(options->type));
|
||||
auto maybe_parsed_type = Web::MimeSniff::MimeType::parse(options->type);
|
||||
|
||||
if (maybe_parsed_type.has_value())
|
||||
type = maybe_parsed_type->serialized();
|
||||
|
|
|
@ -87,8 +87,8 @@ WebIDL::ExceptionOr<FileReader::Result> FileReader::blob_package_data(JS::Realm&
|
|||
auto maybe_type = MimeSniff::MimeType::parse(mime_type.value());
|
||||
|
||||
// 2. If type is not failure, set encoding to the result of getting an encoding from type’s parameters["charset"].
|
||||
if (!maybe_type.is_error() && maybe_type.value().has_value()) {
|
||||
auto type = maybe_type.release_value().value();
|
||||
if (maybe_type.has_value()) {
|
||||
auto const& type = maybe_type.value();
|
||||
auto it = type.parameters().find("charset"sv);
|
||||
if (it != type.parameters().end())
|
||||
encoding = TextCodec::get_standardized_encoding(it->value);
|
||||
|
|
|
@ -246,7 +246,7 @@ FileFilter HTMLInputElement::parse_accept_attribute() const
|
|||
|
||||
// A valid MIME type string with no parameters
|
||||
// Indicates that files of the specified type are accepted.
|
||||
else if (auto mime_type = MUST(MimeSniff::MimeType::parse(value)); mime_type.has_value() && mime_type->parameters().is_empty())
|
||||
else if (auto mime_type = MimeSniff::MimeType::parse(value); mime_type.has_value() && mime_type->parameters().is_empty())
|
||||
filter.add_filter(FileFilter::MimeType { mime_type->essence() });
|
||||
|
||||
// A string whose first character is a U+002E FULL STOP character (.)
|
||||
|
|
|
@ -186,7 +186,7 @@ Bindings::CanPlayTypeResult HTMLMediaElement::can_play_type(StringView type) con
|
|||
if (type == "application/octet-stream"sv)
|
||||
return Bindings::CanPlayTypeResult::Empty;
|
||||
|
||||
auto mime_type = MUST(MimeSniff::MimeType::parse(type));
|
||||
auto mime_type = MimeSniff::MimeType::parse(type);
|
||||
|
||||
if (mime_type.has_value() && mime_type->type() == "video"sv) {
|
||||
if (mime_type->subtype() == "webm"sv)
|
||||
|
|
|
@ -246,7 +246,7 @@ void HTMLObjectElement::resource_did_load()
|
|||
|
||||
// 2. If the type specified in the resource's Content-Type metadata is "text/plain", and the result of applying the rules for distinguishing if a resource is text or binary to the resource is that the resource is not text/plain, then set binary to true.
|
||||
if (content_type == "text/plain"sv) {
|
||||
auto supplied_type = MimeSniff::MimeType::parse(content_type).release_value_but_fixme_should_propagate_errors();
|
||||
auto supplied_type = MimeSniff::MimeType::parse(content_type);
|
||||
auto computed_type = MimeSniff::Resource::sniff(resource()->encoded_data(), MimeSniff::SniffingConfiguration {
|
||||
.sniffing_context = MimeSniff::SniffingContext::TextOrBinary,
|
||||
.supplied_type = move(supplied_type),
|
||||
|
@ -311,7 +311,7 @@ void HTMLObjectElement::run_object_representation_handler_steps(Optional<ByteStr
|
|||
run_object_representation_fallback_steps();
|
||||
return;
|
||||
}
|
||||
auto mime_type = MimeSniff::MimeType::parse(*resource_type).release_value_but_fixme_should_propagate_errors();
|
||||
auto mime_type = MimeSniff::MimeType::parse(*resource_type);
|
||||
|
||||
// * If the resource type is an XML MIME type, or if the resource type does not start with "image/"
|
||||
if (mime_type.has_value() && can_load_document_with_type(*mime_type) && (mime_type->is_xml() || !mime_type->is_image())) {
|
||||
|
|
|
@ -23,7 +23,7 @@ bool is_javascript_mime_type_essence_match(StringView string)
|
|||
{
|
||||
// A string is a JavaScript MIME type essence match if it is an ASCII case-insensitive match for one of the JavaScript MIME type essence strings.
|
||||
// NOTE: The mime type parser automatically lowercases the essence.
|
||||
auto type = MimeType::parse(string).release_value_but_fixme_should_propagate_errors();
|
||||
auto type = MimeType::parse(string);
|
||||
if (!type.has_value())
|
||||
return false;
|
||||
return type->is_javascript();
|
||||
|
@ -81,8 +81,12 @@ MimeType MimeType::create(String type, String subtype)
|
|||
}
|
||||
|
||||
// https://mimesniff.spec.whatwg.org/#parse-a-mime-type
|
||||
ErrorOr<Optional<MimeType>> MimeType::parse(StringView string)
|
||||
Optional<MimeType> MimeType::parse(StringView string)
|
||||
{
|
||||
// Verify that the input string is valid UTF-8 first, so we don't have to think about it anymore.
|
||||
if (!Utf8View(string).validate())
|
||||
return OptionalNone {};
|
||||
|
||||
// 1. Remove any leading and trailing HTTP whitespace from input.
|
||||
auto trimmed_string = string.trim(Fetch::Infrastructure::HTTP_WHITESPACE, TrimMode::Both);
|
||||
|
||||
|
@ -114,7 +118,7 @@ ErrorOr<Optional<MimeType>> MimeType::parse(StringView string)
|
|||
return OptionalNone {};
|
||||
|
||||
// 10. Let mimeType be a new MIME type record whose type is type, in ASCII lowercase, and subtype is subtype, in ASCII lowercase.
|
||||
auto mime_type = MimeType::create(TRY(Infra::to_ascii_lowercase(type)), TRY(Infra::to_ascii_lowercase(subtype)));
|
||||
auto mime_type = MimeType::create(MUST(Infra::to_ascii_lowercase(type)), MUST(Infra::to_ascii_lowercase(subtype)));
|
||||
|
||||
// 11. While position is not past the end of input:
|
||||
while (!lexer.is_eof()) {
|
||||
|
@ -130,7 +134,7 @@ ErrorOr<Optional<MimeType>> MimeType::parse(StringView string)
|
|||
});
|
||||
|
||||
// 4. Set parameterName to parameterName, in ASCII lowercase.
|
||||
auto parameter_name = TRY(Infra::to_ascii_lowercase(parameter_name_view));
|
||||
auto parameter_name = MUST(Infra::to_ascii_lowercase(parameter_name_view));
|
||||
|
||||
// 5. If position is not past the end of input, then:
|
||||
if (!lexer.is_eof()) {
|
||||
|
@ -162,10 +166,10 @@ ErrorOr<Optional<MimeType>> MimeType::parse(StringView string)
|
|||
// 9. Otherwise:
|
||||
else {
|
||||
// 1. Set parameterValue to the result of collecting a sequence of code points that are not U+003B (;) from input, given position.
|
||||
parameter_value = TRY(String::from_utf8(lexer.consume_until(';')));
|
||||
parameter_value = String::from_utf8_without_validation(lexer.consume_until(';').bytes());
|
||||
|
||||
// 2. Remove any trailing HTTP whitespace from parameterValue.
|
||||
parameter_value = TRY(parameter_value.trim(Fetch::Infrastructure::HTTP_WHITESPACE, TrimMode::Right));
|
||||
parameter_value = MUST(parameter_value.trim(Fetch::Infrastructure::HTTP_WHITESPACE, TrimMode::Right));
|
||||
|
||||
// 3. If parameterValue is the empty string, then continue.
|
||||
if (parameter_value.is_empty())
|
||||
|
@ -183,7 +187,7 @@ ErrorOr<Optional<MimeType>> MimeType::parse(StringView string)
|
|||
// - mimeType’s parameters[parameterName] does not exist
|
||||
&& !mime_type.m_parameters.contains(parameter_name)) {
|
||||
// then set mimeType’s parameters[parameterName] to parameterValue.
|
||||
TRY(mime_type.m_parameters.try_set(move(parameter_name), move(parameter_value)));
|
||||
mime_type.m_parameters.set(move(parameter_name), move(parameter_value));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,8 +17,8 @@ bool is_javascript_mime_type_essence_match(StringView);
|
|||
// https://mimesniff.spec.whatwg.org/#mime-type
|
||||
class MimeType {
|
||||
public:
|
||||
static MimeType create(String type, String subtype);
|
||||
static ErrorOr<Optional<MimeType>> parse(StringView);
|
||||
[[nodiscard]] static MimeType create(String type, String subtype);
|
||||
[[nodiscard]] static Optional<MimeType> parse(StringView);
|
||||
|
||||
MimeType(MimeType const&);
|
||||
MimeType& operator=(MimeType const&);
|
||||
|
|
|
@ -388,7 +388,7 @@ ErrorOr<MimeType> rules_for_identifying_an_unknown_mime_type(Resource const& res
|
|||
|
||||
// 2. If patternMatched is true, return the value in the fourth column of row.
|
||||
if (pattern_matched) {
|
||||
if (auto maybe_type = TRY(MimeType::parse(row.mime_type)); maybe_type.has_value())
|
||||
if (auto maybe_type = MimeType::parse(row.mime_type); maybe_type.has_value())
|
||||
return maybe_type.release_value();
|
||||
}
|
||||
}
|
||||
|
@ -419,7 +419,7 @@ ErrorOr<MimeType> rules_for_identifying_an_unknown_mime_type(Resource const& res
|
|||
|
||||
// 2. If patternMatched is true, return the value in the fourth column of row.
|
||||
if (pattern_matched) {
|
||||
if (auto maybe_type = TRY(MimeType::parse(row.mime_type)); maybe_type.has_value())
|
||||
if (auto maybe_type = MimeType::parse(row.mime_type); maybe_type.has_value())
|
||||
return maybe_type.release_value();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -597,7 +597,7 @@ WebIDL::ExceptionOr<void> XMLHttpRequest::send(Optional<DocumentOrXMLHttpRequest
|
|||
// 1. If body is a Document or a USVString, then:
|
||||
if (body->has<JS::Handle<DOM::Document>>() || body->has<String>()) {
|
||||
// 1. Let contentTypeRecord be the result of parsing originalAuthorContentType.
|
||||
auto content_type_record = TRY_OR_THROW_OOM(vm, MimeSniff::MimeType::parse(original_author_content_type.value()));
|
||||
auto content_type_record = MimeSniff::MimeType::parse(original_author_content_type.value());
|
||||
|
||||
// 2. If contentTypeRecord is not failure, contentTypeRecord’s parameters["charset"] exists, and parameters["charset"] is not an ASCII case-insensitive match for "UTF-8", then:
|
||||
if (content_type_record.has_value()) {
|
||||
|
@ -1031,14 +1031,12 @@ WebIDL::ExceptionOr<String> XMLHttpRequest::get_all_response_headers() const
|
|||
// https://xhr.spec.whatwg.org/#dom-xmlhttprequest-overridemimetype
|
||||
WebIDL::ExceptionOr<void> XMLHttpRequest::override_mime_type(String const& mime)
|
||||
{
|
||||
auto& vm = this->vm();
|
||||
|
||||
// 1. If this’s state is loading or done, then throw an "InvalidStateError" DOMException.
|
||||
if (m_state == State::Loading || m_state == State::Done)
|
||||
return WebIDL::InvalidStateError::create(realm(), "Cannot override MIME type when state is Loading or Done."_string);
|
||||
|
||||
// 2. Set this’s override MIME type to the result of parsing mime.
|
||||
m_override_mime_type = TRY_OR_THROW_OOM(vm, MimeSniff::MimeType::parse(mime));
|
||||
m_override_mime_type = MimeSniff::MimeType::parse(mime);
|
||||
|
||||
// 3. If this’s override MIME type is failure, then set this’s override MIME type to application/octet-stream.
|
||||
if (!m_override_mime_type.has_value())
|
||||
|
|
Loading…
Reference in a new issue