[dconf/wip/reorg: 506/523] gvdb-reader: robustness improvements



commit 374cb1bc87a64efe48f3aac2b0c71c395792d42d
Author: Ryan Lortie <desrt desrt ca>
Date:   Fri Jul 6 21:42:04 2012 -0400

    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.

 gvdb-reader.c |   49 ++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 36 insertions(+), 13 deletions(-)
---
diff --git a/gvdb-reader.c b/gvdb-reader.c
index c04630d..b41fb5d 100644
--- a/gvdb-reader.c
+++ b/gvdb-reader.c
@@ -457,7 +457,15 @@ gboolean
 gvdb_table_has_value (GvdbTable    *file,
                       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 *
@@ -699,23 +707,38 @@ gvdb_table_walk (GvdbTable         *table,
           item = gvdb_table_get_item (table, *pointers[index]++);
  start_here:
 
-          if (item != NULL &&
-              (name = gvdb_table_item_get_key (table, item, &name_len)))
+          if (item != NULL && (name = gvdb_table_item_get_key (table, item, &name_len)))
             {
               if (item->type == 'L')
                 {
-                  if (open_func (name, name_len, user_data))
-                    {
-                      guint length;
+                  const guint32_le *dir;
+                  guint length;
 
-                      index++;
-                      g_assert (index < 64);
+                  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++;
+                          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')



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]