gvdb: Fix error handling in gvdb_table_new()

The documentation was unclear about what error codes would be returned
on attempting to open an empty or corrupt GVDB file. Previous versions
of the documentation incorrectly said that corrupt GVDB files were
considered equivalent to empty ones.

A recent commit has clarified the documentation to include its error
handling behaviour.

Update the two users of GVDB within GLib, GResource and GSettingsSource,
to follow this change, and add unit tests for them both.

Other users of the GVDB copylib will need to update their copy and make
appropriate changes if they have bugs in their handling of this
situation. dconf is one example of this. GVDB should be updated from
https://gitlab.gnome.org/GNOME/gvdb.

Signed-off-by: Philip Withnall <withnall@endlessm.com>

https://gitlab.gnome.org/GNOME/glib/issues/1454
This commit is contained in:
Philip Withnall
2018-08-01 13:03:07 +01:00
parent c652d45c97
commit 614adf8a75
4 changed files with 109 additions and 4 deletions

View File

@@ -2353,6 +2353,18 @@ test_schema_source (void)
g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT);
g_clear_error (&error);
/* Test error handling of corrupt compiled files. */
source = g_settings_schema_source_new_from_directory ("schema-source-corrupt", parent, TRUE, &error);
g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL);
g_assert_null (source);
g_clear_error (&error);
/* Test error handling of empty compiled files. */
source = g_settings_schema_source_new_from_directory ("schema-source-empty", parent, TRUE, &error);
g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL);
g_assert_null (source);
g_clear_error (&error);
/* create a source with the parent */
source = g_settings_schema_source_new_from_directory ("schema-source", parent, TRUE, &error);
g_assert_no_error (error);
@@ -2770,6 +2782,12 @@ main (int argc, char *argv[])
if (!g_test_subprocess ())
{
GError *local_error = NULL;
/* A GVDB header is 6 guint32s, and requires a magic number in the first
* two guint32s. A set of zero bytes of a greater length is considered
* corrupt. */
const guint8 gschemas_compiled_corrupt[sizeof (guint32) * 7] = { 0, };
backend_set = g_getenv ("GSETTINGS_BACKEND") != NULL;
g_setenv ("XDG_DATA_DIRS", ".", TRUE);
@@ -2821,6 +2839,21 @@ main (int argc, char *argv[])
"--schema-file=" SRCDIR "/org.gtk.schemasourcecheck.gschema.xml",
NULL, NULL, &result, NULL));
g_assert (result == 0);
g_remove ("schema-source-corrupt/gschemas.compiled");
g_mkdir ("schema-source-corrupt", 0777);
g_file_set_contents ("schema-source-corrupt/gschemas.compiled",
(const gchar *) gschemas_compiled_corrupt,
sizeof (gschemas_compiled_corrupt),
&local_error);
g_assert_no_error (local_error);
g_remove ("schema-source-empty/gschemas.compiled");
g_mkdir ("schema-source-empty", 0777);
g_file_set_contents ("schema-source-empty/gschemas.compiled",
"", 0,
&local_error);
g_assert_no_error (local_error);
}
g_test_add_func ("/gsettings/basic", test_basic);

View File

@@ -317,6 +317,45 @@ test_resource_data_unaligned (void)
g_resource_unref (resource);
}
/* Test error handling for corrupt GResource files (specifically, a corrupt
* GVDB header). */
static void
test_resource_data_corrupt (void)
{
/* A GVDB header is 6 guint32s, and requires a magic number in the first two
* guint32s. A set of zero bytes of a greater length is considered corrupt. */
static const guint8 data[sizeof (guint32) * 7] = { 0, };
GBytes *bytes = NULL;
GResource *resource = NULL;
GError *local_error = NULL;
bytes = g_bytes_new_static (data, sizeof (data));
resource = g_resource_new_from_data (bytes, &local_error);
g_bytes_unref (bytes);
g_assert_error (local_error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_INTERNAL);
g_assert_null (resource);
g_clear_error (&local_error);
}
/* Test handling for empty GResource files. They should also be treated as
* corrupt. */
static void
test_resource_data_empty (void)
{
GBytes *bytes = NULL;
GResource *resource = NULL;
GError *local_error = NULL;
bytes = g_bytes_new_static (NULL, 0);
resource = g_resource_new_from_data (bytes, &local_error);
g_bytes_unref (bytes);
g_assert_error (local_error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_INTERNAL);
g_assert_null (resource);
g_clear_error (&local_error);
}
static void
test_resource_registered (void)
{
@@ -785,6 +824,8 @@ main (int argc,
g_test_add_func ("/resource/file-path", test_resource_file_path);
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/data-corrupt", test_resource_data_corrupt);
g_test_add_func ("/resource/data-empty", test_resource_data_empty);
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);