233 lines
8.4 KiB
Diff
233 lines
8.4 KiB
Diff
|
Backport of:
|
|||
|
|
|||
|
From 221c26685354dea2b2732df94404e8e5e77a1591 Mon Sep 17 00:00:00 2001
|
|||
|
From: Philip Withnall <pwithnall@endlessos.org>
|
|||
|
Date: Wed, 10 Feb 2021 21:21:36 +0000
|
|||
|
Subject: [PATCH 3/3] tests: Add tests for key name handling in the keyfile
|
|||
|
backend
|
|||
|
|
|||
|
This tests the two recent commits.
|
|||
|
|
|||
|
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
|
|||
|
---
|
|||
|
gio/tests/gsettings.c | 171 +++++++++++++++++++++++++++++++++++++++++-
|
|||
|
1 file changed, 170 insertions(+), 1 deletion(-)
|
|||
|
|
|||
|
diff --git a/gio/tests/gsettings.c b/gio/tests/gsettings.c
|
|||
|
index baadca8f5..afe594a23 100644
|
|||
|
--- a/gio/tests/gsettings.c
|
|||
|
+++ b/gio/tests/gsettings.c
|
|||
|
@@ -1,3 +1,4 @@
|
|||
|
+#include <errno.h>
|
|||
|
#include <stdlib.h>
|
|||
|
#include <locale.h>
|
|||
|
#include <libintl.h>
|
|||
|
@@ -1740,6 +1741,14 @@ key_changed_cb (GSettings *settings, const gchar *key, gpointer data)
|
|||
|
(*b) = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
+typedef struct
|
|||
|
+{
|
|||
|
+ const gchar *path;
|
|||
|
+ const gchar *root_group;
|
|||
|
+ const gchar *keyfile_group;
|
|||
|
+ const gchar *root_path;
|
|||
|
+} KeyfileTestData;
|
|||
|
+
|
|||
|
/*
|
|||
|
* Test that using a keyfile works
|
|||
|
*/
|
|||
|
@@ -1834,7 +1843,11 @@ test_keyfile (Fixture *fixture,
|
|||
|
g_free (str);
|
|||
|
|
|||
|
g_settings_set (settings, "farewell", "s", "cheerio");
|
|||
|
-
|
|||
|
+
|
|||
|
+ /* Check that empty keys/groups are not allowed. */
|
|||
|
+ g_assert_false (g_settings_is_writable (settings, ""));
|
|||
|
+ g_assert_false (g_settings_is_writable (settings, "/"));
|
|||
|
+
|
|||
|
/* When executing as root, changing the mode of the keyfile will have
|
|||
|
* no effect on the writability of the settings.
|
|||
|
*/
|
|||
|
@@ -1866,6 +1879,149 @@ test_keyfile (Fixture *fixture,
|
|||
|
g_free (keyfile_path);
|
|||
|
}
|
|||
|
|
|||
|
+/*
|
|||
|
+ * Test that using a keyfile works with a schema with no path set.
|
|||
|
+ */
|
|||
|
+static void
|
|||
|
+test_keyfile_no_path (Fixture *fixture,
|
|||
|
+ gconstpointer user_data)
|
|||
|
+{
|
|||
|
+ const KeyfileTestData *test_data = user_data;
|
|||
|
+ GSettingsBackend *kf_backend;
|
|||
|
+ GSettings *settings;
|
|||
|
+ GKeyFile *keyfile;
|
|||
|
+ gboolean writable;
|
|||
|
+ gchar *key = NULL;
|
|||
|
+ GError *error = NULL;
|
|||
|
+ gchar *keyfile_path = NULL, *store_path = NULL;
|
|||
|
+
|
|||
|
+ keyfile_path = g_build_filename (fixture->tmp_dir, "keyfile", NULL);
|
|||
|
+ store_path = g_build_filename (keyfile_path, "gsettings.store", NULL);
|
|||
|
+ kf_backend = g_keyfile_settings_backend_new (store_path, test_data->root_path, test_data->root_group);
|
|||
|
+ settings = g_settings_new_with_backend_and_path ("org.gtk.test.no-path", kf_backend, test_data->path);
|
|||
|
+ g_object_unref (kf_backend);
|
|||
|
+
|
|||
|
+ g_settings_reset (settings, "test-boolean");
|
|||
|
+ g_assert_true (g_settings_get_boolean (settings, "test-boolean"));
|
|||
|
+
|
|||
|
+ writable = g_settings_is_writable (settings, "test-boolean");
|
|||
|
+ g_assert_true (writable);
|
|||
|
+ g_settings_set (settings, "test-boolean", "b", FALSE);
|
|||
|
+
|
|||
|
+ g_assert_false (g_settings_get_boolean (settings, "test-boolean"));
|
|||
|
+
|
|||
|
+ g_settings_delay (settings);
|
|||
|
+ g_settings_set (settings, "test-boolean", "b", TRUE);
|
|||
|
+ g_settings_apply (settings);
|
|||
|
+
|
|||
|
+ keyfile = g_key_file_new ();
|
|||
|
+ g_assert_true (g_key_file_load_from_file (keyfile, store_path, 0, NULL));
|
|||
|
+
|
|||
|
+ g_assert_true (g_key_file_get_boolean (keyfile, test_data->keyfile_group, "test-boolean", NULL));
|
|||
|
+
|
|||
|
+ g_key_file_free (keyfile);
|
|||
|
+
|
|||
|
+ g_settings_reset (settings, "test-boolean");
|
|||
|
+ g_settings_apply (settings);
|
|||
|
+ keyfile = g_key_file_new ();
|
|||
|
+ g_assert_true (g_key_file_load_from_file (keyfile, store_path, 0, NULL));
|
|||
|
+
|
|||
|
+ g_assert_false (g_key_file_get_string (keyfile, test_data->keyfile_group, "test-boolean", &error));
|
|||
|
+ g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND);
|
|||
|
+ g_clear_error (&error);
|
|||
|
+
|
|||
|
+ /* Check that empty keys/groups are not allowed. */
|
|||
|
+ g_assert_false (g_settings_is_writable (settings, ""));
|
|||
|
+ g_assert_false (g_settings_is_writable (settings, "/"));
|
|||
|
+
|
|||
|
+ /* Keys which ghost the root group name are not allowed. This can only be
|
|||
|
+ * tested when the path is `/` as otherwise it acts as a prefix and prevents
|
|||
|
+ * any ghosting. */
|
|||
|
+ if (g_str_equal (test_data->path, "/"))
|
|||
|
+ {
|
|||
|
+ key = g_strdup_printf ("%s/%s", test_data->root_group, "");
|
|||
|
+ g_assert_false (g_settings_is_writable (settings, key));
|
|||
|
+ g_free (key);
|
|||
|
+
|
|||
|
+ key = g_strdup_printf ("%s/%s", test_data->root_group, "/");
|
|||
|
+ g_assert_false (g_settings_is_writable (settings, key));
|
|||
|
+ g_free (key);
|
|||
|
+
|
|||
|
+ key = g_strdup_printf ("%s/%s", test_data->root_group, "test-boolean");
|
|||
|
+ g_assert_false (g_settings_is_writable (settings, key));
|
|||
|
+ g_free (key);
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ g_key_file_free (keyfile);
|
|||
|
+ g_object_unref (settings);
|
|||
|
+
|
|||
|
+ /* Clean up the temporary directory. */
|
|||
|
+ g_assert_cmpint (g_chmod (keyfile_path, 0777) == 0 ? 0 : errno, ==, 0);
|
|||
|
+ g_assert_cmpint (g_remove (store_path) == 0 ? 0 : errno, ==, 0);
|
|||
|
+ g_assert_cmpint (g_rmdir (keyfile_path) == 0 ? 0 : errno, ==, 0);
|
|||
|
+ g_free (store_path);
|
|||
|
+ g_free (keyfile_path);
|
|||
|
+}
|
|||
|
+
|
|||
|
+/*
|
|||
|
+ * Test that a keyfile rejects writes to keys outside its root path.
|
|||
|
+ */
|
|||
|
+static void
|
|||
|
+test_keyfile_outside_root_path (Fixture *fixture,
|
|||
|
+ gconstpointer user_data)
|
|||
|
+{
|
|||
|
+ GSettingsBackend *kf_backend;
|
|||
|
+ GSettings *settings;
|
|||
|
+ gchar *keyfile_path = NULL, *store_path = NULL;
|
|||
|
+
|
|||
|
+ keyfile_path = g_build_filename (fixture->tmp_dir, "keyfile", NULL);
|
|||
|
+ store_path = g_build_filename (keyfile_path, "gsettings.store", NULL);
|
|||
|
+ kf_backend = g_keyfile_settings_backend_new (store_path, "/tests/basic-types/", "root");
|
|||
|
+ settings = g_settings_new_with_backend_and_path ("org.gtk.test.no-path", kf_backend, "/tests/");
|
|||
|
+ g_object_unref (kf_backend);
|
|||
|
+
|
|||
|
+ g_assert_false (g_settings_is_writable (settings, "test-boolean"));
|
|||
|
+
|
|||
|
+ g_object_unref (settings);
|
|||
|
+
|
|||
|
+ /* Clean up the temporary directory. The keyfile probably doesn’t exist, so
|
|||
|
+ * don’t error on failure. */
|
|||
|
+ g_remove (store_path);
|
|||
|
+ g_assert_cmpint (g_rmdir (keyfile_path) == 0 ? 0 : errno, ==, 0);
|
|||
|
+ g_free (store_path);
|
|||
|
+ g_free (keyfile_path);
|
|||
|
+}
|
|||
|
+
|
|||
|
+/*
|
|||
|
+ * Test that a keyfile rejects writes to keys in the root if no root group is set.
|
|||
|
+ */
|
|||
|
+static void
|
|||
|
+test_keyfile_no_root_group (Fixture *fixture,
|
|||
|
+ gconstpointer user_data)
|
|||
|
+{
|
|||
|
+ GSettingsBackend *kf_backend;
|
|||
|
+ GSettings *settings;
|
|||
|
+ gchar *keyfile_path = NULL, *store_path = NULL;
|
|||
|
+
|
|||
|
+ keyfile_path = g_build_filename (fixture->tmp_dir, "keyfile", NULL);
|
|||
|
+ store_path = g_build_filename (keyfile_path, "gsettings.store", NULL);
|
|||
|
+ kf_backend = g_keyfile_settings_backend_new (store_path, "/", NULL);
|
|||
|
+ settings = g_settings_new_with_backend_and_path ("org.gtk.test.no-path", kf_backend, "/");
|
|||
|
+ g_object_unref (kf_backend);
|
|||
|
+
|
|||
|
+ g_assert_false (g_settings_is_writable (settings, "test-boolean"));
|
|||
|
+ g_assert_true (g_settings_is_writable (settings, "child/test-boolean"));
|
|||
|
+
|
|||
|
+ g_object_unref (settings);
|
|||
|
+
|
|||
|
+ /* Clean up the temporary directory. The keyfile probably doesn’t exist, so
|
|||
|
+ * don’t error on failure. */
|
|||
|
+ g_remove (store_path);
|
|||
|
+ g_assert_cmpint (g_rmdir (keyfile_path) == 0 ? 0 : errno, ==, 0);
|
|||
|
+ g_free (store_path);
|
|||
|
+ g_free (keyfile_path);
|
|||
|
+}
|
|||
|
+
|
|||
|
/* Test that getting child schemas works
|
|||
|
*/
|
|||
|
static void
|
|||
|
@@ -2844,6 +3000,14 @@ main (int argc, char *argv[])
|
|||
|
gchar *override_text;
|
|||
|
gchar *enums;
|
|||
|
gint result;
|
|||
|
+ const KeyfileTestData keyfile_test_data_explicit_path = { "/tests/", "root", "tests", "/" };
|
|||
|
+ const KeyfileTestData keyfile_test_data_empty_path = { "/", "root", "root", "/" };
|
|||
|
+ const KeyfileTestData keyfile_test_data_long_path = {
|
|||
|
+ "/tests/path/is/very/long/and/this/makes/some/comparisons/take/a/different/branch/",
|
|||
|
+ "root",
|
|||
|
+ "tests/path/is/very/long/and/this/makes/some/comparisons/take/a/different/branch",
|
|||
|
+ "/"
|
|||
|
+ };
|
|||
|
|
|||
|
/* Meson build sets this */
|
|||
|
#ifdef TEST_LOCALE_PATH
|
|||
|
@@ -2967,6 +3131,11 @@ main (int argc, char *argv[])
|
|||
|
}
|
|||
|
|
|||
|
g_test_add ("/gsettings/keyfile", Fixture, NULL, setup, test_keyfile, teardown);
|
|||
|
+ g_test_add ("/gsettings/keyfile/explicit-path", Fixture, &keyfile_test_data_explicit_path, setup, test_keyfile_no_path, teardown);
|
|||
|
+ g_test_add ("/gsettings/keyfile/empty-path", Fixture, &keyfile_test_data_empty_path, setup, test_keyfile_no_path, teardown);
|
|||
|
+ g_test_add ("/gsettings/keyfile/long-path", Fixture, &keyfile_test_data_long_path, setup, test_keyfile_no_path, teardown);
|
|||
|
+ g_test_add ("/gsettings/keyfile/outside-root-path", Fixture, NULL, setup, test_keyfile_outside_root_path, teardown);
|
|||
|
+ g_test_add ("/gsettings/keyfile/no-root-group", Fixture, NULL, setup, test_keyfile_no_root_group, teardown);
|
|||
|
g_test_add_func ("/gsettings/child-schema", test_child_schema);
|
|||
|
g_test_add_func ("/gsettings/strinfo", test_strinfo);
|
|||
|
g_test_add_func ("/gsettings/enums", test_enums);
|
|||
|
--
|
|||
|
2.30.1
|
|||
|
|