glocalfileinfo: Increase size of the content-type sniff buffer to 16KiB

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 <pwithnall@gnome.org>

Fixes: #3186
This commit is contained in:
Philip Withnall 2023-11-27 13:14:39 +00:00
parent 40081f9b62
commit 01cdce7573

View File

@ -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 doesnt 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);