[Libguestfs] [PATCH hivex 12/19] lib: get_children: Refactor this into two functions.

Richard W.M. Jones rjones at redhat.com
Thu Jul 25 10:38:54 UTC 2013


From: "Richard W.M. Jones" <rjones at redhat.com>

Although this change seems rather large, including removing a large
block of dead code, there should be no functional change.
---
 lib/node.c | 122 +++++++++++++++++++++++++++----------------------------------
 1 file changed, 54 insertions(+), 68 deletions(-)

diff --git a/lib/node.c b/lib/node.c
index 1255a84..91c85e6 100644
--- a/lib/node.c
+++ b/lib/node.c
@@ -184,6 +184,10 @@ hivex_node_classname (hive_h *h, hive_node_h node)
 }
 #endif
 
+static int _get_children (hive_h *h, hive_node_h blkoff,
+                          offset_list *children, offset_list *blocks,
+                          int flags);
+
 /* Iterate over children (ie. subkeys of a node), returning child
  * nodes and intermediate blocks.
  *
@@ -255,11 +259,45 @@ _hivex_get_children (hive_h *h, hive_node_h node,
     goto error;
   }
 
-  if (_hivex_add_to_offset_list (&blocks, subkey_lf) == -1)
+  if (_get_children (h, subkey_lf, &children, &blocks, flags) == -1)
     goto error;
 
+  /* Check the number of children we ended up reading matches
+   * nr_subkeys_in_nk.
+   */
+  size_t nr_children = _hivex_get_offset_list_length (&children);
+  if (nr_subkeys_in_nk != nr_children) {
+    SET_ERRNO (ENOTSUP,
+               "nr_subkeys_in_nk = %zu "
+               "is not equal to number of children read %zu",
+               nr_subkeys_in_nk, nr_children);
+    goto error;
+  }
+
+ out:
+  *children_ret = _hivex_return_offset_list (&children);
+  *blocks_ret = _hivex_return_offset_list (&blocks);
+  if (!*children_ret || !*blocks_ret)
+    goto error;
+  return 0;
+
+ error:
+  _hivex_free_offset_list (&children);
+  _hivex_free_offset_list (&blocks);
+  return -1;
+}
+
+static int
+_get_children (hive_h *h, hive_node_h blkoff,
+               offset_list *children, offset_list *blocks,
+               int flags)
+{
+  /* Add this intermediate block. */
+  if (_hivex_add_to_offset_list (blocks, blkoff) == -1)
+    return -1;
+
   struct ntreg_hbin_block *block =
-    (struct ntreg_hbin_block *) ((char *) h->addr + subkey_lf);
+    (struct ntreg_hbin_block *) ((char *) h->addr + blkoff);
 
   /* Points to lf-record?  (Note, also "lh" but that is basically the
    * same as "lf" as far as we are concerned here).
@@ -272,17 +310,10 @@ _hivex_get_children (hive_h *h, hive_node_h node,
      */
     size_t nr_subkeys_in_lf = le16toh (lf->nr_keys);
 
-    if (nr_subkeys_in_nk != nr_subkeys_in_lf) {
-      SET_ERRNO (ENOTSUP,
-                 "nr_subkeys_in_nk = %zu is not equal to nr_subkeys_in_lf = %zu",
-                 nr_subkeys_in_nk, nr_subkeys_in_lf);
-      goto error;
-    }
-
-    size_t len = block_len (h, subkey_lf, NULL);
+    size_t len = block_len (h, blkoff, NULL);
     if (8 + nr_subkeys_in_lf * 8 > len) {
       SET_ERRNO (EFAULT, "too many subkeys (%zu, %zu)", nr_subkeys_in_lf, len);
-      goto error;
+      return -1;
     }
 
     size_t i;
@@ -292,11 +323,11 @@ _hivex_get_children (hive_h *h, hive_node_h node,
       if (!(flags & GET_CHILDREN_NO_CHECK_NK)) {
         if (!IS_VALID_BLOCK (h, subkey)) {
           SET_ERRNO (EFAULT, "subkey is not a valid block (0x%zx)", subkey);
-          goto error;
+          return -1;
         }
       }
-      if (_hivex_add_to_offset_list (&children, subkey) == -1)
-        goto error;
+      if (_hivex_add_to_offset_list (children, subkey) == -1)
+        return -1;
     }
   }
   /* Points to ri-record? */
@@ -305,14 +336,14 @@ _hivex_get_children (hive_h *h, hive_node_h node,
 
     size_t nr_offsets = le16toh (ri->nr_offsets);
 
-    /* Count total number of children. */
-    size_t i, count = 0;
+    /* Copy list of children. */
+    size_t i;
     for (i = 0; i < nr_offsets; ++i) {
       hive_node_h offset = le32toh (ri->offset[i]);
       offset += 0x1000;
       if (!IS_VALID_BLOCK (h, offset)) {
         SET_ERRNO (EFAULT, "ri-offset is not a valid block (0x%zx)", offset);
-        goto error;
+        return -1;
       }
       if (!BLOCK_ID_EQ (h, offset, "lf") && !BLOCK_ID_EQ (h, offset, "lh")) {
         struct ntreg_lf_record *block =
@@ -320,42 +351,7 @@ _hivex_get_children (hive_h *h, hive_node_h node,
         SET_ERRNO (ENOTSUP,
                    "ri-record offset does not point to lf/lh (0x%zx, %d, %d)",
                    offset, block->id[0], block->id[1]);
-        goto error;
-      }
-
-      if (_hivex_add_to_offset_list (&blocks, offset) == -1)
-        goto error;
-
-      struct ntreg_lf_record *lf =
-        (struct ntreg_lf_record *) ((char *) h->addr + offset);
-
-      count += le16toh (lf->nr_keys);
-    }
-
-    if (nr_subkeys_in_nk != count) {
-      SET_ERRNO (ENOTSUP,
-                 "nr_subkeys_in_nk = %zu is not equal to counted = %zu",
-                 nr_subkeys_in_nk, count);
-      goto error;
-    }
-
-    /* Copy list of children.  Note nr_subkeys_in_nk is limited to
-     * something reasonable above.
-     */
-    for (i = 0; i < nr_offsets; ++i) {
-      hive_node_h offset = le32toh (ri->offset[i]);
-      offset += 0x1000;
-      if (!IS_VALID_BLOCK (h, offset)) {
-        SET_ERRNO (EFAULT, "ri-offset is not a valid block (0x%zx)", offset);
-        goto error;
-      }
-      if (!BLOCK_ID_EQ (h, offset, "lf") && !BLOCK_ID_EQ (h, offset, "lh")) {
-        struct ntreg_lf_record *block =
-          (struct ntreg_lf_record *) ((char *) h->addr + offset);
-        SET_ERRNO (ENOTSUP,
-                   "ri-record offset does not point to lf/lh (0x%zx, %d, %d)",
-                   offset, block->id[0], block->id[1]);
-        goto error;
+        return -1;
       }
 
       struct ntreg_lf_record *lf =
@@ -370,32 +366,22 @@ _hivex_get_children (hive_h *h, hive_node_h node,
             SET_ERRNO (EFAULT,
                        "indirect subkey is not a valid block (0x%zx)",
                        subkey);
-            goto error;
+            return -1;
           }
         }
-        if (_hivex_add_to_offset_list (&children, subkey) == -1)
-          goto error;
+        if (_hivex_add_to_offset_list (children, subkey) == -1)
+          return -1;
       }
     }
   }
   else {
     SET_ERRNO (ENOTSUP,
                "subkey block is not lf/lh/ri (0x%zx, %d, %d)",
-               subkey_lf, block->id[0], block->id[1]);
-    goto error;
+               blkoff, block->id[0], block->id[1]);
+    return -1;
   }
 
- out:
-  *children_ret = _hivex_return_offset_list (&children);
-  *blocks_ret = _hivex_return_offset_list (&blocks);
-  if (!*children_ret || !*blocks_ret)
-    goto error;
   return 0;
-
- error:
-  _hivex_free_offset_list (&children);
-  _hivex_free_offset_list (&blocks);
-  return -1;
 }
 
 hive_node_h *
-- 
1.8.3.1




More information about the Libguestfs mailing list