LibCore: Add offsets to binary signature matching

Some file signatures are at an offset into the file, so we need to be
able to specify an offset to start matching bytes at.
This commit is contained in:
Valtteri Koskivuori 2021-05-18 20:19:27 +03:00 committed by Linus Groh
parent 105bbc457d
commit 241b378e4b
Notes: sideshowbarker 2024-07-18 17:49:06 +09:00

View file

@ -85,38 +85,38 @@ String guess_mime_type_based_on_filename(const StringView& path)
return "text/plain";
}
#define ENUMERATE_HEADER_CONTENTS \
__ENUMERATE_MIME_TYPE_HEADER(bmp, "image/bmp", 2, 'B', 'M') \
__ENUMERATE_MIME_TYPE_HEADER(bzip2, "application/x-bzip2", 3, 'B', 'Z', 'h') \
__ENUMERATE_MIME_TYPE_HEADER(elf, "extra/elf", 4, 0x7F, 'E', 'L', 'F') \
__ENUMERATE_MIME_TYPE_HEADER(flac, "extra/flac", 4, 0x66, 0x4C, 0x61, 0x43) \
__ENUMERATE_MIME_TYPE_HEADER(gif_87, "image/gif", 6, 'G', 'I', 'F', '8', '7', 'a') \
__ENUMERATE_MIME_TYPE_HEADER(gif_89, "image/gif", 6, 'G', 'I', 'F', '8', '9', 'a') \
__ENUMERATE_MIME_TYPE_HEADER(gzip, "application/gzip", 2, 0x1F, 0x8B) \
__ENUMERATE_MIME_TYPE_HEADER(jpeg, "image/jpeg", 4, 0xFF, 0xD8, 0xFF, 0xDB) \
__ENUMERATE_MIME_TYPE_HEADER(jpeg_huh, "image/jpeg", 4, 0xFF, 0xD8, 0xFF, 0xEE) \
__ENUMERATE_MIME_TYPE_HEADER(jpeg_jfif, "image/jpeg", 12, 0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 'J', 'F', 'I', 'F', 0x00, 0x01) \
__ENUMERATE_MIME_TYPE_HEADER(midi, "audio/midi", 4, 0x4D, 0x54, 0x68, 0x64) \
__ENUMERATE_MIME_TYPE_HEADER(pbm, "image/x-portable-bitmap", 3, 0x50, 0x31, 0x0A) \
__ENUMERATE_MIME_TYPE_HEADER(pgm, "image/x-portable-graymap", 3, 0x50, 0x32, 0x0A) \
__ENUMERATE_MIME_TYPE_HEADER(png, "image/png", 8, 0x89, 'P', 'N', 'G', 0x0D, 0x0A, 0x1A, 0x0A) \
__ENUMERATE_MIME_TYPE_HEADER(ppm, "image/x-portable-pixmap", 3, 0x50, 0x33, 0x0A) \
__ENUMERATE_MIME_TYPE_HEADER(sevenzip, "application/x-7z-compressed", 6, 0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C) \
__ENUMERATE_MIME_TYPE_HEADER(shell, "text/x-shellscript", 10, '#', '!', '/', 'b', 'i', 'n', '/', 's', 'h', '\n') \
__ENUMERATE_MIME_TYPE_HEADER(sqlite, "extra/sqlite", 16, 'S', 'Q', 'L', 'i', 't', 'e', ' ', 'f', 'o', 'r', 'm', 'a', 't', ' ', '3', 0x00) \
__ENUMERATE_MIME_TYPE_HEADER(tiff, "image/tiff", 4, 'I', 'I', '*', 0x00) \
__ENUMERATE_MIME_TYPE_HEADER(tiff_bigendian, "image/tiff", 4, 'M', 'M', 0x00, '*')
#define ENUMERATE_HEADER_CONTENTS \
__ENUMERATE_MIME_TYPE_HEADER(bmp, "image/bmp", 0, 2, 'B', 'M') \
__ENUMERATE_MIME_TYPE_HEADER(bzip2, "application/x-bzip2", 0, 3, 'B', 'Z', 'h') \
__ENUMERATE_MIME_TYPE_HEADER(elf, "extra/elf", 0, 4, 0x7F, 'E', 'L', 'F') \
__ENUMERATE_MIME_TYPE_HEADER(flac, "extra/flac", 0, 4, 0x66, 0x4C, 0x61, 0x43) \
__ENUMERATE_MIME_TYPE_HEADER(gif_87, "image/gif", 0, 6, 'G', 'I', 'F', '8', '7', 'a') \
__ENUMERATE_MIME_TYPE_HEADER(gif_89, "image/gif", 0, 6, 'G', 'I', 'F', '8', '9', 'a') \
__ENUMERATE_MIME_TYPE_HEADER(gzip, "application/gzip", 0, 2, 0x1F, 0x8B) \
__ENUMERATE_MIME_TYPE_HEADER(jpeg, "image/jpeg", 0, 4, 0xFF, 0xD8, 0xFF, 0xDB) \
__ENUMERATE_MIME_TYPE_HEADER(jpeg_huh, "image/jpeg", 0, 4, 0xFF, 0xD8, 0xFF, 0xEE) \
__ENUMERATE_MIME_TYPE_HEADER(jpeg_jfif, "image/jpeg", 0, 12, 0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 'J', 'F', 'I', 'F', 0x00, 0x01) \
__ENUMERATE_MIME_TYPE_HEADER(midi, "audio/midi", 0, 4, 0x4D, 0x54, 0x68, 0x64) \
__ENUMERATE_MIME_TYPE_HEADER(pbm, "image/x-portable-bitmap", 0, 3, 0x50, 0x31, 0x0A) \
__ENUMERATE_MIME_TYPE_HEADER(pgm, "image/x-portable-graymap", 0, 3, 0x50, 0x32, 0x0A) \
__ENUMERATE_MIME_TYPE_HEADER(png, "image/png", 0, 8, 0x89, 'P', 'N', 'G', 0x0D, 0x0A, 0x1A, 0x0A) \
__ENUMERATE_MIME_TYPE_HEADER(ppm, "image/x-portable-pixmap", 0, 3, 0x50, 0x33, 0x0A) \
__ENUMERATE_MIME_TYPE_HEADER(sevenzip, "application/x-7z-compressed", 0, 6, 0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C) \
__ENUMERATE_MIME_TYPE_HEADER(shell, "text/x-shellscript", 0, 10, '#', '!', '/', 'b', 'i', 'n', '/', 's', 'h', '\n') \
__ENUMERATE_MIME_TYPE_HEADER(sqlite, "extra/sqlite", 0, 16, 'S', 'Q', 'L', 'i', 't', 'e', ' ', 'f', 'o', 'r', 'm', 'a', 't', ' ', '3', 0x00) \
__ENUMERATE_MIME_TYPE_HEADER(tiff, "image/tiff", 0, 4, 'I', 'I', '*', 0x00) \
__ENUMERATE_MIME_TYPE_HEADER(tiff_bigendian, "image/tiff", 0, 4, 'M', 'M', 0x00, '*')
#define __ENUMERATE_MIME_TYPE_HEADER(var_name, mime_type, pattern_size, ...) \
static const u8 var_name##_arr[pattern_size] = { __VA_ARGS__ }; \
#define __ENUMERATE_MIME_TYPE_HEADER(var_name, mime_type, pattern_offset, pattern_size, ...) \
static const u8 var_name##_arr[pattern_size] = { __VA_ARGS__ }; \
static constexpr ReadonlyBytes var_name = ReadonlyBytes { var_name##_arr, pattern_size };
ENUMERATE_HEADER_CONTENTS
#undef __ENUMERATE_MIME_TYPE_HEADER
Optional<String> guess_mime_type_based_on_sniffed_bytes(const ReadonlyBytes& bytes)
{
#define __ENUMERATE_MIME_TYPE_HEADER(var_name, mime_type, pattern_size, ...) \
if (bytes.starts_with(var_name)) \
#define __ENUMERATE_MIME_TYPE_HEADER(var_name, mime_type, pattern_offset, pattern_size, ...) \
if (static_cast<ssize_t>(bytes.size()) >= pattern_offset && bytes.slice(pattern_offset).starts_with(var_name)) \
return mime_type;
ENUMERATE_HEADER_CONTENTS;
#undef __ENUMERATE_MIME_TYPE_HEADER