Commit 27898916 authored by Allison Karlitskaya's avatar Allison Karlitskaya

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.
parent d1e4f3dd
......@@ -701,7 +701,61 @@ g_settings_schema_list (GSettingsSchema *schema,
for (i = 0; i < len; i++)
if (list[i][0] != '.')
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)
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))))
g_variant_unref (child_schema);
/* Schema is not found -> don't add it to the list */
if (child_table == NULL)
/* 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);
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);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment