From 01cdce75738741f0f490ede838027963e143f184 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Mon, 27 Nov 2023 13:14:39 +0000 Subject: [PATCH] glocalfileinfo: Increase size of the content-type sniff buffer to 16KiB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was previously 4KiB, but this isn’t enough for sniffing the content-type of some GPT disk images (they use 4KiB sectors, and the magic bytes are in the second sector). A buffer of 8KiB would work, but 16KiB seems harmless and more future proof. Most of the time, the buffer size should be set by xdgmime anyway, based on the largest sniff buffer its database needs. Currently (with shared-mime-info master) that’s 18730 bytes, so even with a 16KiB buffer we’re going to potentially mis-identify a few file types. Tested manually by modifying the example GPT image from shared-mime-info (https://gitlab.freedesktop.org/xdg/shared-mime-info/-/blob/master/tests/mime-detection/disk.gpt) to remove the magic at offset 0x200 and add it instead at offset 0x1000, then running: ``` cp shared-mime-info.git/tests/mime-detection/disk.gpt ./disk-without-extension gio info -a standard::content-type ./disk-without-extension ``` It should print `application/vnd.efi.img` rather than `application/octet-stream`. Signed-off-by: Philip Withnall Fixes: #3186 --- gio/glocalfileinfo.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/gio/glocalfileinfo.c b/gio/glocalfileinfo.c index 4f51427f5..2df7c91e5 100644 --- a/gio/glocalfileinfo.c +++ b/gio/glocalfileinfo.c @@ -1345,7 +1345,11 @@ get_content_type (const char *basename, #if !defined(G_OS_WIN32) && !defined(__APPLE__) if (!fast && result_uncertain && path != NULL) { - guchar sniff_buffer[4096]; + /* Sniff the first 16KiB of the file (sometimes less, if xdgmime + * says it doesn’t need so much). Most files need less than 4KiB of + * sniffing, but some disk images need more (see + * https://gitlab.gnome.org/GNOME/glib/-/issues/3186). */ + guchar sniff_buffer[16384]; gsize sniff_length; #ifdef O_NOATIME int errsv; @@ -1353,8 +1357,8 @@ get_content_type (const char *basename, int fd; sniff_length = _g_unix_content_type_get_sniff_len (); - if (sniff_length == 0 || sniff_length > 4096) - sniff_length = 4096; + if (sniff_length == 0 || sniff_length > sizeof (sniff_buffer)) + sniff_length = sizeof (sniff_buffer); #ifdef O_NOATIME fd = g_open (path, O_RDONLY | O_NOATIME | O_CLOEXEC, 0);