GResource – Create an internal copy of the GBytes if it is not pointer aligned

https://bugzilla.gnome.org/show_bug.cgi?id=790030
This commit is contained in:
Sebastian Dröge 2017-11-13 11:47:06 +01:00
parent 3c9c01e3ce
commit 7b60708204
2 changed files with 44 additions and 1 deletions

View File

@ -525,7 +525,8 @@ g_resource_new_from_table (GvdbTable *table)
* to register it with g_resources_register(). * to register it with g_resources_register().
* *
* Note: @data must be backed by memory that is at least pointer aligned. * 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 * Returns: (transfer full): a new #GResource, or %NULL on error
* *
@ -536,6 +537,14 @@ g_resource_new_from_data (GBytes *data,
GError **error) GError **error)
{ {
GvdbTable *table; 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), table = gvdb_table_new_from_data (g_bytes_get_data (data, NULL),
g_bytes_get_size (data), g_bytes_get_size (data),
@ -545,6 +554,9 @@ g_resource_new_from_data (GBytes *data,
(GDestroyNotify)g_bytes_unref, (GDestroyNotify)g_bytes_unref,
error); error);
if (unref_data)
g_bytes_unref (data);
if (table == NULL) if (table == NULL)
return NULL; return NULL;

View File

@ -180,6 +180,36 @@ test_resource_data (void)
g_resource_unref (resource); 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 static void
test_resource_registered (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/file", test_resource_file);
g_test_add_func ("/resource/data", test_resource_data); 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/registered", test_resource_registered);
g_test_add_func ("/resource/manual", test_resource_manual); g_test_add_func ("/resource/manual", test_resource_manual);
g_test_add_func ("/resource/manual2", test_resource_manual2); g_test_add_func ("/resource/manual2", test_resource_manual2);