mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-10 03:04:05 +02:00
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
This commit is contained in:
@@ -701,7 +701,61 @@ g_settings_schema_list (GSettingsSchema *schema,
|
|||||||
|
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
if (list[i][0] != '.')
|
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;
|
schema->n_items = j;
|
||||||
|
|
||||||
g_strfreev (list);
|
g_strfreev (list);
|
||||||
|
Reference in New Issue
Block a user