mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 23:27:35 +00:00
LibWeb/MimeSniff: Add the image type pattern matching algorithm
This commit is contained in:
parent
2babc08c17
commit
62ca3b518b
2 changed files with 54 additions and 2 deletions
|
@ -64,6 +64,12 @@ TEST_CASE(compute_unknown_mime_type)
|
||||||
"\xEF\xBB\xBF\x00"sv,
|
"\xEF\xBB\xBF\x00"sv,
|
||||||
"Hello world!"sv,
|
"Hello world!"sv,
|
||||||
});
|
});
|
||||||
|
mime_type_to_headers_map.set("image/x-icon"sv, { "\x00\x00\x01\x00"sv, "\x00\x00\x02\x00"sv });
|
||||||
|
mime_type_to_headers_map.set("image/bmp"sv, { "BM"sv });
|
||||||
|
mime_type_to_headers_map.set("image/gif"sv, { "GIF87a"sv, "GIF89a"sv });
|
||||||
|
mime_type_to_headers_map.set("image/webp"sv, { "RIFF\x00\x00\x00\x00WEBPVP"sv });
|
||||||
|
mime_type_to_headers_map.set("image/png"sv, { "\x89PNG\x0D\x0A\x1A\x0A"sv });
|
||||||
|
mime_type_to_headers_map.set("image/jpeg"sv, { "\xFF\xD8\xFF"sv });
|
||||||
|
|
||||||
for (auto const& mime_type_to_headers : mime_type_to_headers_map) {
|
for (auto const& mime_type_to_headers : mime_type_to_headers_map) {
|
||||||
auto mime_type = mime_type_to_headers.key;
|
auto mime_type = mime_type_to_headers.key;
|
||||||
|
|
|
@ -90,6 +90,52 @@ bool pattern_matching_algorithm(ReadonlyBytes input, ReadonlyBytes pattern, Read
|
||||||
|
|
||||||
ReadonlyBytes constexpr no_ignored_bytes;
|
ReadonlyBytes constexpr no_ignored_bytes;
|
||||||
|
|
||||||
|
// https://mimesniff.spec.whatwg.org/#matching-an-image-type-pattern
|
||||||
|
ErrorOr<Optional<MimeType>> match_an_image_type_pattern(ReadonlyBytes input)
|
||||||
|
{
|
||||||
|
// 1. Execute the following steps for each row row in the following table:
|
||||||
|
static Array<BytePatternTableRow, 8> constexpr pattern_table {
|
||||||
|
// A Windows Icon signature.
|
||||||
|
BytePatternTableRow { "\x00\x00\x01\x00"sv, "\xFF\xFF\xFF\xFF"sv, no_ignored_bytes, "image/x-icon"sv },
|
||||||
|
|
||||||
|
// A Windows Cursor signature.
|
||||||
|
BytePatternTableRow { "\x00\x00\x02\x00"sv, "\xFF\xFF\xFF\xFF"sv, no_ignored_bytes, "image/x-icon"sv },
|
||||||
|
|
||||||
|
// The string "BM", a BMP signature.
|
||||||
|
BytePatternTableRow { "\x42\x4D"sv, "\xFF\xFF"sv, no_ignored_bytes, "image/bmp"sv },
|
||||||
|
|
||||||
|
// The string "GIF87a", a GIF signature.
|
||||||
|
BytePatternTableRow { "\x47\x49\x46\x38\x37\x61"sv, "\xFF\xFF\xFF\xFF\xFF\xFF"sv, no_ignored_bytes, "image/gif"sv },
|
||||||
|
|
||||||
|
// The string "GIF89a", a GIF signature.
|
||||||
|
BytePatternTableRow { "\x47\x49\x46\x38\x39\x61"sv, "\xFF\xFF\xFF\xFF\xFF\xFF"sv, no_ignored_bytes, "image/gif"sv },
|
||||||
|
|
||||||
|
// The string "RIFF" followed by four bytes followed by the string "WEBPVP".
|
||||||
|
BytePatternTableRow { "\x52\x49\x46\x46\x00\x00\x00\x00\x57\x45\x42\x50\x56\x50"sv,
|
||||||
|
"\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF"sv, no_ignored_bytes, "image/webp"sv },
|
||||||
|
|
||||||
|
// An error-checking byte followed by the string "PNG" followed by CR LF SUB LF, the PNG signature.
|
||||||
|
BytePatternTableRow { "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A"sv, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"sv, no_ignored_bytes, "image/png"sv },
|
||||||
|
|
||||||
|
// The JPEG Start of Image marker followed by the indicator byte of another marker.
|
||||||
|
BytePatternTableRow { "\xFF\xD8\xFF"sv, "\xFF\xFF\xFF"sv, no_ignored_bytes, "image/jpeg"sv },
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto const& row : pattern_table) {
|
||||||
|
// 1. Let patternMatched be the result of the pattern matching algorithm given input, the value in
|
||||||
|
// the first column of row, the value in the second column of row, and the value in the third
|
||||||
|
// column of row.
|
||||||
|
auto pattern_matched = pattern_matching_algorithm(input, row.byte_pattern.bytes(), row.pattern_mask.bytes(), row.ignored_leading_bytes);
|
||||||
|
|
||||||
|
// 2. If patternMatched is true, return the value in the fourth column of row.
|
||||||
|
if (pattern_matched)
|
||||||
|
return MimeType::parse(row.mime_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Return undefined.
|
||||||
|
return OptionalNone {};
|
||||||
|
}
|
||||||
|
|
||||||
// https://mimesniff.spec.whatwg.org/#rules-for-identifying-an-unknown-mime-type
|
// https://mimesniff.spec.whatwg.org/#rules-for-identifying-an-unknown-mime-type
|
||||||
ErrorOr<MimeType> rules_for_identifying_an_unknown_mime_type(Resource const& resource, bool sniff_scriptable = false)
|
ErrorOr<MimeType> rules_for_identifying_an_unknown_mime_type(Resource const& resource, bool sniff_scriptable = false)
|
||||||
{
|
{
|
||||||
|
@ -208,8 +254,8 @@ ErrorOr<MimeType> rules_for_identifying_an_unknown_mime_type(Resource const& res
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: 3. Let matchedType be the result of executing the image type pattern matching algorithm given resource’s resource header.
|
// 3. Let matchedType be the result of executing the image type pattern matching algorithm given resource’s resource header.
|
||||||
Optional<MimeType> matched_type;
|
auto matched_type = TRY(match_an_image_type_pattern(resource.resource_header()));
|
||||||
|
|
||||||
// 4. If matchedType is not undefined, return matchedType.
|
// 4. If matchedType is not undefined, return matchedType.
|
||||||
if (matched_type.has_value())
|
if (matched_type.has_value())
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue