[glib/glib-2-38] g_settings_list_children: only list viable schemas
- From: Ryan Lortie <desrt src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/glib-2-38] g_settings_list_children: only list viable schemas
- Date: Wed, 2 Oct 2013 16:38:41 +0000 (UTC)
commit d01bded1939967ee4deafbe1facfe567205b6c9c
Author: Ryan Lortie <desrt desrt ca>
Date: Thu Aug 8 18:50:21 2013 +0200
g_settings_list_children: only list viable schemas
Don't return children with invalid schemas from
g_settings_list_children() (ie: missing schemas or mismatched paths).
This prevents gsettings list-recursively from crashing when broken
schemas are installed on the system.
https://bugzilla.gnome.org/show_bug.cgi?id=705688
gio/gsettingsschema.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 55 insertions(+), 1 deletions(-)
---
diff --git a/gio/gsettingsschema.c b/gio/gsettingsschema.c
index 3592836..fe43b89 100644
--- a/gio/gsettingsschema.c
+++ b/gio/gsettingsschema.c
@@ -701,7 +701,61 @@ g_settings_schema_list (GSettingsSchema *schema,
for (i = 0; i < len; i++)
if (list[i][0] != '.')
- schema->items[j++] = g_quark_from_string (list[i]);
+ {
+ if (g_str_has_suffix (list[i], "/"))
+ {
+ /* This is a child. Check to make sure that
+ * instantiating the child would actually work before we
+ * return it from list() and cause a crash.
+ */
+ GSettingsSchemaSource *source;
+ GVariant *child_schema;
+ GvdbTable *child_table;
+
+ child_schema = gvdb_table_get_raw_value (schema->table, list[i]);
+ if (!child_schema)
+ continue;
+
+ child_table = NULL;
+
+ for (source = schema_sources; source; source = source->parent)
+ if ((child_table = gvdb_table_get_table (source->table, g_variant_get_string
(child_schema, NULL))))
+ break;
+
+ g_variant_unref (child_schema);
+
+ /* Schema is not found -> don't add it to the list */
+ if (child_table == NULL)
+ continue;
+
+ /* Make sure the schema is relocatable or at the
+ * expected path
+ */
+ if (gvdb_table_has_value (child_table, ".path"))
+ {
+ GVariant *path;
+ gchar *expected;
+ gboolean same;
+
+ path = gvdb_table_get_raw_value (child_table, ".path");
+ expected = g_strconcat (schema->path, list[i], NULL);
+ same = g_str_equal (expected, g_variant_get_string (path, NULL));
+ g_variant_unref (path);
+ g_free (expected);
+
+ if (!same)
+ {
+ gvdb_table_unref (child_table);
+ continue;
+ }
+ }
+
+ gvdb_table_unref (child_table);
+ /* Else, it's good... */
+ }
+
+ schema->items[j++] = g_quark_from_string (list[i]);
+ }
schema->n_items = j;
g_strfreev (list);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]