mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-15 00:36:19 +01:00
gvdb-reader: robustness improvements
Improve the robustness of gvdb-reader in two ways. First: ensure that the result of gvdb_table_has_value() always agrees with gvdb_table_get_value(). Those two could disagree in the case that the value was recorded as existing but pointed to an out-of-bounds region. Second: prevent gvdb_table_walk() from getting stuck in finite loops due to self-referential directories.
This commit is contained in:
parent
a9551ccf92
commit
374cb1bc87
@ -457,7 +457,15 @@ gboolean
|
|||||||
gvdb_table_has_value (GvdbTable *file,
|
gvdb_table_has_value (GvdbTable *file,
|
||||||
const gchar *key)
|
const gchar *key)
|
||||||
{
|
{
|
||||||
return gvdb_table_lookup (file, key, 'v') != NULL;
|
static const struct gvdb_hash_item *item;
|
||||||
|
gsize size;
|
||||||
|
|
||||||
|
item = gvdb_table_lookup (file, key, 'v');
|
||||||
|
|
||||||
|
if (item == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return gvdb_table_dereference (file, &item->value.pointer, 8, &size) != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GVariant *
|
static GVariant *
|
||||||
@ -699,23 +707,38 @@ gvdb_table_walk (GvdbTable *table,
|
|||||||
item = gvdb_table_get_item (table, *pointers[index]++);
|
item = gvdb_table_get_item (table, *pointers[index]++);
|
||||||
start_here:
|
start_here:
|
||||||
|
|
||||||
if (item != NULL &&
|
if (item != NULL && (name = gvdb_table_item_get_key (table, item, &name_len)))
|
||||||
(name = gvdb_table_item_get_key (table, item, &name_len)))
|
|
||||||
{
|
{
|
||||||
if (item->type == 'L')
|
if (item->type == 'L')
|
||||||
{
|
{
|
||||||
if (open_func (name, name_len, user_data))
|
const guint32_le *dir;
|
||||||
{
|
|
||||||
guint length;
|
guint length;
|
||||||
|
|
||||||
|
if (gvdb_table_list_from_item (table, item, &dir, &length))
|
||||||
|
{
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
/* In order to avoid files with recursive contents
|
||||||
|
* we impose the rule that a directory's data must
|
||||||
|
* follow the data of any directory pointing to
|
||||||
|
* it.
|
||||||
|
*
|
||||||
|
* If we discover that our newly-discovered
|
||||||
|
* directory follows the one we're traversing now
|
||||||
|
* then bail out.
|
||||||
|
*/
|
||||||
|
if (dir <= pointers[index])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (open_func (name, name_len, user_data))
|
||||||
|
{
|
||||||
index++;
|
index++;
|
||||||
g_assert (index < 64);
|
g_assert (index < 64);
|
||||||
|
|
||||||
gvdb_table_list_from_item (table, item,
|
|
||||||
&pointers[index],
|
|
||||||
&length);
|
|
||||||
enders[index] = pointers[index] + length;
|
|
||||||
name_lengths[index] = name_len;
|
name_lengths[index] = name_len;
|
||||||
|
pointers[index] = dir;
|
||||||
|
enders[index] = pointers[index] + length;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (item->type == 'v')
|
else if (item->type == 'v')
|
||||||
|
Loading…
Reference in New Issue
Block a user