From 7b60708204354da877f7eda5150631223bba42f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 13 Nov 2017 11:47:06 +0100 Subject: [PATCH] =?UTF-8?q?GResource=20=E2=80=93=20Create=20an=20internal?= =?UTF-8?q?=20copy=20of=20the=20GBytes=20if=20it=20is=20not=20pointer=20al?= =?UTF-8?q?igned?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://bugzilla.gnome.org/show_bug.cgi?id=790030 --- gio/gresource.c | 14 +++++++++++++- gio/tests/resources.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/gio/gresource.c b/gio/gresource.c index ed0e474a4..f38de86f5 100644 --- a/gio/gresource.c +++ b/gio/gresource.c @@ -525,7 +525,8 @@ g_resource_new_from_table (GvdbTable *table) * to register it with g_resources_register(). * * Note: @data must be backed by memory that is at least pointer aligned. - * Otherwise this function will fail and exit the process. + * Otherwise this function will internally create a copy of the memory since + * GLib 2.56, or in older versions fail and exit the process. * * Returns: (transfer full): a new #GResource, or %NULL on error * @@ -536,6 +537,14 @@ g_resource_new_from_data (GBytes *data, GError **error) { GvdbTable *table; + gboolean unref_data = FALSE; + + if (((guintptr) g_bytes_get_data (data, NULL)) % sizeof (gpointer) != 0) + { + data = g_bytes_new (g_bytes_get_data (data, NULL), + g_bytes_get_size (data)); + unref_data = TRUE; + } table = gvdb_table_new_from_data (g_bytes_get_data (data, NULL), g_bytes_get_size (data), @@ -545,6 +554,9 @@ g_resource_new_from_data (GBytes *data, (GDestroyNotify)g_bytes_unref, error); + if (unref_data) + g_bytes_unref (data); + if (table == NULL) return NULL; diff --git a/gio/tests/resources.c b/gio/tests/resources.c index b002325b8..22ce7c657 100644 --- a/gio/tests/resources.c +++ b/gio/tests/resources.c @@ -180,6 +180,36 @@ test_resource_data (void) g_resource_unref (resource); } +static void +test_resource_data_unaligned (void) +{ + GResource *resource; + GError *error = NULL; + gboolean loaded_file; + char *content, *content_copy; + gsize content_size; + GBytes *data; + + loaded_file = g_file_get_contents (g_test_get_filename (G_TEST_BUILT, "test.gresource", NULL), + &content, &content_size, NULL); + g_assert (loaded_file); + + content_copy = g_new (char, content_size + 1); + memcpy (content_copy + 1, content, content_size); + + data = g_bytes_new_with_free_func (content_copy + 1, content_size, + (GDestroyNotify) g_free, content_copy); + g_free (content); + resource = g_resource_new_from_data (data, &error); + g_bytes_unref (data); + g_assert (resource != NULL); + g_assert_no_error (error); + + test_resource (resource); + + g_resource_unref (resource); +} + static void test_resource_registered (void) { @@ -644,6 +674,7 @@ main (int argc, g_test_add_func ("/resource/file", test_resource_file); g_test_add_func ("/resource/data", test_resource_data); + g_test_add_func ("/resource/data_unaligned", test_resource_data_unaligned); g_test_add_func ("/resource/registered", test_resource_registered); g_test_add_func ("/resource/manual", test_resource_manual); g_test_add_func ("/resource/manual2", test_resource_manual2);