From 305727381697e464680204862d75b42ebf4a0b20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Tue, 13 Sep 2022 05:38:21 +0200 Subject: [PATCH] glocalfileinfo: Ensure we always sniff some data to get the content type In case the XDG database is not initialized yet we may try to sniff a 0-length data, making our content-type routines to mark non-empty files as `application/x-zerosize`. This is wrong, so in case the sniff size is not set, let's just try to read the default value. To avoid false-application/x-zerosize results (that are not something we want as per legacy assumptions). See: https://bugzilla.gnome.org/show_bug.cgi?id=755795 Fixes: https://gitlab.gnome.org/GNOME/glib/-/issues/2742 --- gio/glocalfileinfo.c | 2 +- gio/tests/file.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/gio/glocalfileinfo.c b/gio/glocalfileinfo.c index b2a497a44..d92ad78f5 100644 --- a/gio/glocalfileinfo.c +++ b/gio/glocalfileinfo.c @@ -1388,7 +1388,7 @@ get_content_type (const char *basename, int fd, errsv; sniff_length = _g_unix_content_type_get_sniff_len (); - if (sniff_length > 4096) + if (sniff_length == 0 || sniff_length > 4096) sniff_length = 4096; #ifdef O_NOATIME diff --git a/gio/tests/file.c b/gio/tests/file.c index 9d98ff205..36dccac66 100644 --- a/gio/tests/file.c +++ b/gio/tests/file.c @@ -3524,6 +3524,40 @@ test_query_default_handler_uri (void) g_object_unref (invalid_file); } +static void +test_query_zero_length_content_type (void) +{ + GFile *empty_file; + GFileInfo *file_info; + GError *error = NULL; + GFileIOStream *iostream; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=755795"); + /* This is historic behaviour. See: + * - https://gitlab.gnome.org/GNOME/glib/-/blob/2.74.0/gio/glocalfileinfo.c#L1360-1369 + * - https://bugzilla.gnome.org/show_bug.cgi?id=755795 */ + g_test_summary ("empty files should always be considered text/plain"); + + empty_file = g_file_new_tmp ("empty-file-XXXXXX", &iostream, &error); + g_assert_no_error (error); + + g_io_stream_close (G_IO_STREAM (iostream), NULL, &error); + g_assert_no_error (error); + g_clear_object (&iostream); + + file_info = + g_file_query_info (empty_file, + G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, + G_FILE_QUERY_INFO_NONE, + NULL, &error); + g_assert_no_error (error); + + g_assert_cmpstr (g_file_info_get_content_type (file_info), ==, "text/plain"); + + g_clear_object (&file_info); + g_clear_object (&empty_file); +} + static void test_query_default_handler_file (void) { @@ -3551,6 +3585,9 @@ test_query_default_handler_file (void) NULL, NULL, &error); g_assert_no_error (error); + g_output_stream_flush (output_stream, NULL, &error); + g_assert_no_error (error); + g_output_stream_close (output_stream, NULL, &error); g_assert_no_error (error); g_clear_object (&iostream); @@ -3576,6 +3613,9 @@ test_query_default_handler_file (void) NULL, NULL, &error); g_assert_no_error (error); + g_output_stream_flush (output_stream, NULL, &error); + g_assert_no_error (error); + g_output_stream_close (output_stream, NULL, &error); g_assert_no_error (error); g_clear_object (&iostream); @@ -3772,7 +3812,7 @@ main (int argc, char *argv[]) { setlocale (LC_ALL, ""); - g_test_init (&argc, &argv, NULL); + g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL); g_test_add_func ("/file/basic", test_basic); g_test_add_func ("/file/build-filename", test_build_filename); @@ -3814,6 +3854,7 @@ main (int argc, char *argv[]) g_test_add_func ("/file/writev/async_all-cancellation", test_writev_async_all_cancellation); g_test_add_func ("/file/build-attribute-list-for-copy", test_build_attribute_list_for_copy); g_test_add_func ("/file/move_async", test_move_async); + g_test_add_func ("/file/query-zero-length-content-type", test_query_zero_length_content_type); g_test_add_func ("/file/query-default-handler-file", test_query_default_handler_file); g_test_add_func ("/file/query-default-handler-file-async", test_query_default_handler_file_async); g_test_add_func ("/file/query-default-handler-uri", test_query_default_handler_uri);