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