[Libguestfs] [PATCH hivex 03/19] lib: Move the 'offset_list' struct into a separate compilation unit.

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


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

---
 lib/Makefile.am      |  14 +++----
 lib/hivex-internal.h |  17 ++++++++
 lib/hivex.c          | 104 +++++++++++--------------------------------------
 lib/offset-list.c    | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 155 insertions(+), 88 deletions(-)
 create mode 100644 lib/offset-list.c

diff --git a/lib/Makefile.am b/lib/Makefile.am
index 9a30b41..ea130d4 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -24,13 +24,13 @@ EXTRA_DIST = \
 lib_LTLIBRARIES = libhivex.la
 
 libhivex_la_SOURCES = \
-  hivex.c \
-  hivex.h \
-  hivex-internal.h \
-  byte_conversions.h \
-  gettext.h \
-  mmap.h \
-  hivex.syms
+	byte_conversions.h \
+	gettext.h \
+	hivex.c \
+	hivex.h \
+	hivex-internal.h \
+	mmap.h \
+	offset-list.c
 
 libhivex_la_LIBADD =  ../gnulib/lib/libgnu.la $(LTLIBOBJS)
 libhivex_la_LDFLAGS = \
diff --git a/lib/hivex-internal.h b/lib/hivex-internal.h
index b053850..14aa4d2 100644
--- a/lib/hivex-internal.h
+++ b/lib/hivex-internal.h
@@ -66,6 +66,23 @@ struct hive_h {
 #endif
 };
 
+/* offset-list.c */
+typedef struct offset_list offset_list;
+struct offset_list {
+  hive_h *h;
+  size_t *offsets;
+  size_t len;
+  size_t alloc;
+  size_t limit;
+};
+extern void _hivex_init_offset_list (hive_h *h, offset_list *list);
+extern int _hivex_grow_offset_list (offset_list *list, size_t alloc);
+extern int _hivex_add_to_offset_list (offset_list *list, size_t offset);
+extern size_t _hivex_get_offset_list_length (offset_list *list);
+extern void _hivex_set_offset_list_limit (offset_list *list, size_t limit);
+extern void _hivex_free_offset_list (offset_list *list);
+extern size_t * _hivex_return_offset_list (offset_list *list);
+
 #define STREQ(a,b) (strcmp((a),(b)) == 0)
 #define STRCASEEQ(a,b) (strcasecmp((a),(b)) == 0)
 #define STRNEQ(a,b) (strcmp((a),(b)) != 0)
diff --git a/lib/hivex.c b/lib/hivex.c
index 6f6e207..8fa02a7 100644
--- a/lib/hivex.c
+++ b/lib/hivex.c
@@ -702,66 +702,6 @@ hivex_node_classname (hive_h *h, hive_node_h node)
 }
 #endif
 
-/* Structure for returning 0-terminated lists of offsets (nodes,
- * values, etc).
- */
-struct offset_list {
-  size_t *offsets;
-  size_t len;
-  size_t alloc;
-};
-
-static void
-init_offset_list (struct offset_list *list)
-{
-  list->len = 0;
-  list->alloc = 0;
-  list->offsets = NULL;
-}
-
-#define INIT_OFFSET_LIST(name) \
-  struct offset_list name; \
-  init_offset_list (&name)
-
-/* Preallocates the offset_list, but doesn't make the contents longer. */
-static int
-grow_offset_list (struct offset_list *list, size_t alloc)
-{
-  assert (alloc >= list->len);
-  size_t *p = realloc (list->offsets, alloc * sizeof (size_t));
-  if (p == NULL)
-    return -1;
-  list->offsets = p;
-  list->alloc = alloc;
-  return 0;
-}
-
-static int
-add_to_offset_list (struct offset_list *list, size_t offset)
-{
-  if (list->len >= list->alloc) {
-    if (grow_offset_list (list, list->alloc ? list->alloc * 2 : 4) == -1)
-      return -1;
-  }
-  list->offsets[list->len] = offset;
-  list->len++;
-  return 0;
-}
-
-static void
-free_offset_list (struct offset_list *list)
-{
-  free (list->offsets);
-}
-
-static size_t *
-return_offset_list (struct offset_list *list)
-{
-  if (add_to_offset_list (list, 0) == -1)
-    return NULL;
-  return list->offsets;         /* caller frees */
-}
-
 /* Iterate over children, returning child nodes and intermediate blocks. */
 #define GET_CHILDREN_NO_CHECK_NK 1
 
@@ -780,8 +720,9 @@ get_children (hive_h *h, hive_node_h node,
 
   size_t nr_subkeys_in_nk = le32toh (nk->nr_subkeys);
 
-  INIT_OFFSET_LIST (children);
-  INIT_OFFSET_LIST (blocks);
+  offset_list children, blocks;
+  _hivex_init_offset_list (h, &children);
+  _hivex_init_offset_list (h, &blocks);
 
   /* Deal with the common "no subkeys" case quickly. */
   if (nr_subkeys_in_nk == 0)
@@ -798,7 +739,7 @@ get_children (hive_h *h, hive_node_h node,
   }
 
   /* Preallocate space for the children. */
-  if (grow_offset_list (&children, nr_subkeys_in_nk) == -1)
+  if (_hivex_grow_offset_list (&children, nr_subkeys_in_nk) == -1)
     goto error;
 
   /* The subkey_lf field can point either to an lf-record, which is
@@ -816,7 +757,7 @@ get_children (hive_h *h, hive_node_h node,
     goto error;
   }
 
-  if (add_to_offset_list (&blocks, subkey_lf) == -1)
+  if (_hivex_add_to_offset_list (&blocks, subkey_lf) == -1)
     goto error;
 
   struct ntreg_hbin_block *block =
@@ -867,7 +808,7 @@ get_children (hive_h *h, hive_node_h node,
           goto error;
         }
       }
-      if (add_to_offset_list (&children, subkey) == -1)
+      if (_hivex_add_to_offset_list (&children, subkey) == -1)
         goto error;
     }
     goto ok;
@@ -902,7 +843,7 @@ get_children (hive_h *h, hive_node_h node,
         goto error;
       }
 
-      if (add_to_offset_list (&blocks, offset) == -1)
+      if (_hivex_add_to_offset_list (&blocks, offset) == -1)
         goto error;
 
       struct ntreg_lf_record *lf =
@@ -954,7 +895,7 @@ get_children (hive_h *h, hive_node_h node,
               goto error;
             }
           }
-          if (add_to_offset_list (&children, subkey) == -1)
+          if (_hivex_add_to_offset_list (&children, subkey) == -1)
             goto error;
         }
       } else { /* "lf" or "lh" block */
@@ -975,7 +916,7 @@ get_children (hive_h *h, hive_node_h node,
               goto error;
             }
           }
-          if (add_to_offset_list (&children, subkey) == -1)
+          if (_hivex_add_to_offset_list (&children, subkey) == -1)
             goto error;
         }
       }
@@ -989,13 +930,13 @@ get_children (hive_h *h, hive_node_h node,
              subkey_lf, block->id[0], block->id[1]);
   errno = ENOTSUP;
  error:
-  free_offset_list (&children);
-  free_offset_list (&blocks);
+  _hivex_free_offset_list (&children);
+  _hivex_free_offset_list (&blocks);
   return -1;
 
  ok:
-  *children_ret = return_offset_list (&children);
-  *blocks_ret = return_offset_list (&blocks);
+  *children_ret = _hivex_return_offset_list (&children);
+  *blocks_ret = _hivex_return_offset_list (&blocks);
   if (!*children_ret || !*blocks_ret)
     goto error;
   return 0;
@@ -1085,8 +1026,9 @@ get_values (hive_h *h, hive_node_h node,
   if (h->msglvl >= 2)
     fprintf (stderr, "hivex_node_values: nr_values = %zu\n", nr_values);
 
-  INIT_OFFSET_LIST (values);
-  INIT_OFFSET_LIST (blocks);
+  offset_list values, blocks;
+  _hivex_init_offset_list (h, &values);
+  _hivex_init_offset_list (h, &blocks);
 
   /* Deal with the common "no values" case quickly. */
   if (nr_values == 0)
@@ -1103,7 +1045,7 @@ get_values (hive_h *h, hive_node_h node,
   }
 
   /* Preallocate space for the values. */
-  if (grow_offset_list (&values, nr_values) == -1)
+  if (_hivex_grow_offset_list (&values, nr_values) == -1)
     goto error;
 
   /* Get the value list and check it looks reasonable. */
@@ -1118,7 +1060,7 @@ get_values (hive_h *h, hive_node_h node,
     goto error;
   }
 
-  if (add_to_offset_list (&blocks, vlist_offset) == -1)
+  if (_hivex_add_to_offset_list (&blocks, vlist_offset) == -1)
     goto error;
 
   struct ntreg_value_list *vlist =
@@ -1146,20 +1088,20 @@ get_values (hive_h *h, hive_node_h node,
       errno = EFAULT;
       goto error;
     }
-    if (add_to_offset_list (&values, value) == -1)
+    if (_hivex_add_to_offset_list (&values, value) == -1)
       goto error;
   }
 
  ok:
-  *values_ret = return_offset_list (&values);
-  *blocks_ret = return_offset_list (&blocks);
+  *values_ret = _hivex_return_offset_list (&values);
+  *blocks_ret = _hivex_return_offset_list (&blocks);
   if (!*values_ret || !*blocks_ret)
     goto error;
   return 0;
 
  error:
-  free_offset_list (&values);
-  free_offset_list (&blocks);
+  _hivex_free_offset_list (&values);
+  _hivex_free_offset_list (&blocks);
   return -1;
 }
 
diff --git a/lib/offset-list.c b/lib/offset-list.c
new file mode 100644
index 0000000..b4d9bb7
--- /dev/null
+++ b/lib/offset-list.c
@@ -0,0 +1,108 @@
+/* hivex - Windows Registry "hive" extraction library.
+ * Copyright (C) 2013 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * See file LICENSE for the full license.
+ */
+
+/* Structure for returning 0-terminated lists of offsets (nodes,
+ * values, etc).
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "hivex.h"
+#include "hivex-internal.h"
+
+void
+_hivex_init_offset_list (hive_h *h, offset_list *list)
+{
+  list->h = h;
+  list->len = 0;
+  list->alloc = 0;
+  list->offsets = NULL;
+  list->limit = SIZE_MAX;
+}
+
+/* Preallocates the offset_list, but doesn't make the contents longer. */
+int
+_hivex_grow_offset_list (offset_list *list, size_t alloc)
+{
+  assert (alloc >= list->len);
+  size_t *p = realloc (list->offsets, alloc * sizeof (size_t));
+  if (p == NULL)
+    return -1;
+  list->offsets = p;
+  list->alloc = alloc;
+  return 0;
+}
+
+static int
+add_to_offset_list (offset_list *list, size_t offset)
+{
+  if (list->len >= list->alloc) {
+    if (_hivex_grow_offset_list (list, list->alloc ? list->alloc * 2 : 4) == -1)
+      return -1;
+  }
+  list->offsets[list->len] = offset;
+  list->len++;
+  return 0;
+}
+
+int
+_hivex_add_to_offset_list (offset_list *list, size_t offset)
+{
+  assert (offset != 0);         /* internal error if this happens */
+
+  if (list->len >= list->limit) {
+    if (list->h->msglvl >= 2)
+      fprintf (stderr, "hivex: returning ERANGE because list of offsets "
+               "has exceeded limit (limit = %zu)\n",
+               list->limit);
+    errno = ERANGE;
+    return -1;
+  }
+
+  return add_to_offset_list (list, offset);
+}
+
+size_t
+_hivex_get_offset_list_length (offset_list *list)
+{
+  return list->len;
+}
+
+void
+_hivex_set_offset_list_limit (offset_list *list, size_t limit)
+{
+  list->limit = limit;
+}
+
+void
+_hivex_free_offset_list (offset_list *list)
+{
+  free (list->offsets);
+}
+
+size_t *
+_hivex_return_offset_list (offset_list *list)
+{
+  if (add_to_offset_list (list, 0) == -1)
+    return NULL;
+  return list->offsets;         /* caller frees */
+}
-- 
1.8.3.1




More information about the Libguestfs mailing list