With GCC 4.9.1 I get a -Woverlength-strings warning:
hivex-internal.h:123:23: error: string length ‘3823’ is greater than ...
(STREQLEN (((struct ntreg_hbin_block *)((char *) (h)->addr + (offs)))->id,
(eqid), 2))
The compile command can be shortened to:
cd lib && cpp -DHAVE_CONFIG_H -I.. -I../gnulib/lib -I. \
-Woverlength-strings -Werror -g -O2 write.c
After that, be amazed at the huge assertion string produced by the
macro which is also visible in libhivex.so (two times).
To fix that mess, use an inline function. The `STR*` macros were moved
and a string.h header added since STREQLEN is used in the function.
---
lib/hivex-internal.h | 28 ++++++++++++++++------------
lib/node.c | 18 +++++++++---------
lib/value.c | 14 +++++++-------
lib/write.c | 22 +++++++++++-----------
4 files changed, 43 insertions(+), 39 deletions(-)
diff --git a/lib/hivex-internal.h b/lib/hivex-internal.h
index bfd24c8..e59084d 100644
--- a/lib/hivex-internal.h
+++ b/lib/hivex-internal.h
@@ -21,9 +21,20 @@
#include <stdarg.h>
#include <stddef.h>
+#include <string.h>
#include "byte_conversions.h"
+#define STREQ(a,b) (strcmp((a),(b)) == 0)
+#define STRCASEEQ(a,b) (strcasecmp((a),(b)) == 0)
+#define STRNEQ(a,b) (strcmp((a),(b)) != 0)
+#define STRCASENEQ(a,b) (strcasecmp((a),(b)) != 0)
+#define STREQLEN(a,b,n) (strncmp((a),(b),(n)) == 0)
+#define STRCASEEQLEN(a,b,n) (strncasecmp((a),(b),(n)) == 0)
+#define STRNEQLEN(a,b,n) (strncmp((a),(b),(n)) != 0)
+#define STRCASENEQLEN(a,b,n) (strncasecmp((a),(b),(n)) != 0)
+#define STRPREFIX(a,b) (strncmp((a),(b),strlen((b))) == 0)
+
struct hive_h {
char *filename;
int fd;
@@ -119,8 +130,11 @@ struct ntreg_hbin_block {
/* Block data follows here. */
} __attribute__((__packed__));
-#define BLOCK_ID_EQ(h,offs,eqid) \
- (STREQLEN (((struct ntreg_hbin_block *)((char *) (h)->addr + (offs)))->id,
(eqid), 2))
+static inline int
+block_id_eq (const hive_h *h, size_t offs, const char *eqid)
+{
+ return (STREQLEN (((struct ntreg_hbin_block *)((char *) (h)->addr + (offs)))->id,
(eqid), 2));
+}
struct ntreg_nk_record {
int32_t seg_len; /* length (always -ve because used) */
@@ -285,16 +299,6 @@ extern void _hivex_free_strings (char **argv);
/* value.c */
extern int _hivex_get_values (hive_h *h, hive_node_h node, hive_value_h **values_ret,
size_t **blocks_ret);
-#define STREQ(a,b) (strcmp((a),(b)) == 0)
-#define STRCASEEQ(a,b) (strcasecmp((a),(b)) == 0)
-#define STRNEQ(a,b) (strcmp((a),(b)) != 0)
-#define STRCASENEQ(a,b) (strcasecmp((a),(b)) != 0)
-#define STREQLEN(a,b,n) (strncmp((a),(b),(n)) == 0)
-#define STRCASEEQLEN(a,b,n) (strncasecmp((a),(b),(n)) == 0)
-#define STRNEQLEN(a,b,n) (strncmp((a),(b),(n)) != 0)
-#define STRCASENEQLEN(a,b,n) (strncasecmp((a),(b),(n)) != 0)
-#define STRPREFIX(a,b) (strncmp((a),(b),strlen((b))) == 0)
-
#define DEBUG(lvl,fs,...) \
do { \
if (h->msglvl >= (lvl)) { \
diff --git a/lib/node.c b/lib/node.c
index 22d1861..1fb48cf 100644
--- a/lib/node.c
+++ b/lib/node.c
@@ -49,7 +49,7 @@ hivex_root (hive_h *h)
size_t
hivex_node_struct_length (hive_h *h, hive_node_h node)
{
- if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
+ if (!IS_VALID_BLOCK (h, node) || !block_id_eq (h, node, "nk")) {
SET_ERRNO (EINVAL, "invalid block or not an 'nk' block");
return 0;
}
@@ -71,7 +71,7 @@ hivex_node_struct_length (hive_h *h, hive_node_h node)
char *
hivex_node_name (hive_h *h, hive_node_h node)
{
- if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
+ if (!IS_VALID_BLOCK (h, node) || !block_id_eq (h, node, "nk")) {
SET_ERRNO (EINVAL, "invalid block or not an 'nk' block");
return NULL;
}
@@ -99,7 +99,7 @@ hivex_node_name (hive_h *h, hive_node_h node)
size_t
hivex_node_name_len (hive_h *h, hive_node_h node)
{
- if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
+ if (!IS_VALID_BLOCK (h, node) || !block_id_eq (h, node, "nk")) {
SET_ERRNO (EINVAL, "invalid block or not an 'nk' block");
return 0;
}
@@ -143,7 +143,7 @@ hivex_node_timestamp (hive_h *h, hive_node_h node)
{
int64_t ret;
- if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
+ if (!IS_VALID_BLOCK (h, node) || !block_id_eq (h, node, "nk")) {
SET_ERRNO (EINVAL, "invalid block or not an 'nk' block");
return -1;
}
@@ -165,7 +165,7 @@ hivex_node_timestamp (hive_h *h, hive_node_h node)
hive_security_h
hivex_node_security (hive_h *h, hive_node_h node)
{
- if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
+ if (!IS_VALID_BLOCK (h, node) || !block_id_eq (h, node, "nk")) {
SET_ERRNO (EINVAL, "invalid block or not an 'nk' block");
return 0;
}
@@ -184,7 +184,7 @@ hivex_node_security (hive_h *h, hive_node_h node)
hive_classname_h
hivex_node_classname (hive_h *h, hive_node_h node)
{
- if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
+ if (!IS_VALID_BLOCK (h, node) || !block_id_eq (h, node, "nk")) {
SET_ERRNO (EINVAL, "invalid block or not an 'nk' block");
return 0;
}
@@ -283,7 +283,7 @@ _hivex_get_children (hive_h *h, hive_node_h node,
hive_node_h **children_ret, size_t **blocks_ret,
int flags)
{
- if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
+ if (!IS_VALID_BLOCK (h, node) || !block_id_eq (h, node, "nk")) {
SET_ERRNO (EINVAL, "invalid block or not an 'nk' block");
return -1;
}
@@ -491,7 +491,7 @@ check_child_is_nk_block (hive_h *h, hive_node_h child, int flags)
struct ntreg_hbin_block *block =
(struct ntreg_hbin_block *) ((char *) h->addr + child);
- if (!BLOCK_ID_EQ (h, child, "nk")) {
+ if (!block_id_eq (h, child, "nk")) {
SET_ERRNO (EFAULT, "subkey is not an 'nk' block (0x%zx, %d, %d)",
child, block->id[0], block->id[1]);
return -1;
@@ -546,7 +546,7 @@ hivex_node_get_child (hive_h *h, hive_node_h node, const char *nname)
hive_node_h
hivex_node_parent (hive_h *h, hive_node_h node)
{
- if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
+ if (!IS_VALID_BLOCK (h, node) || !block_id_eq (h, node, "nk")) {
SET_ERRNO (EINVAL, "invalid block or not an 'nk' block");
return 0;
}
diff --git a/lib/value.c b/lib/value.c
index f222b41..1c2356f 100644
--- a/lib/value.c
+++ b/lib/value.c
@@ -37,7 +37,7 @@ int
_hivex_get_values (hive_h *h, hive_node_h node,
hive_value_h **values_ret, size_t **blocks_ret)
{
- if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
+ if (!IS_VALID_BLOCK (h, node) || !block_id_eq (h, node, "nk")) {
SET_ERRNO (EINVAL, "invalid block or not an 'nk' block");
return -1;
}
@@ -175,7 +175,7 @@ hivex_value_struct_length (hive_h *h, hive_value_h value)
size_t
hivex_value_key_len (hive_h *h, hive_value_h value)
{
- if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) {
+ if (!IS_VALID_BLOCK (h, value) || !block_id_eq (h, value, "vk")) {
SET_ERRNO (EINVAL, "invalid block or not an 'vk' block");
return 0;
}
@@ -199,7 +199,7 @@ hivex_value_key_len (hive_h *h, hive_value_h value)
char *
hivex_value_key (hive_h *h, hive_value_h value)
{
- if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) {
+ if (!IS_VALID_BLOCK (h, value) || !block_id_eq (h, value, "vk")) {
SET_ERRNO (EINVAL, "invalid block or not an 'vk' block");
return 0;
}
@@ -225,7 +225,7 @@ hivex_value_key (hive_h *h, hive_value_h value)
int
hivex_value_type (hive_h *h, hive_value_h value, hive_type *t, size_t *len)
{
- if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) {
+ if (!IS_VALID_BLOCK (h, value) || !block_id_eq (h, value, "vk")) {
SET_ERRNO (EINVAL, "invalid block or not an 'vk' block");
return -1;
}
@@ -247,7 +247,7 @@ hivex_value_type (hive_h *h, hive_value_h value, hive_type *t, size_t
*len)
hive_value_h
hivex_value_data_cell_offset (hive_h *h, hive_value_h value, size_t *len)
{
- if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) {
+ if (!IS_VALID_BLOCK (h, value) || !block_id_eq (h, value, "vk")) {
SET_ERRNO (EINVAL, "invalid block or not an 'vk' block");
return 0;
}
@@ -300,7 +300,7 @@ char *
hivex_value_value (hive_h *h, hive_value_h value,
hive_type *t_rtn, size_t *len_rtn)
{
- if (!IS_VALID_BLOCK (h, value) || !BLOCK_ID_EQ (h, value, "vk")) {
+ if (!IS_VALID_BLOCK (h, value) || !block_id_eq (h, value, "vk")) {
SET_ERRNO (EINVAL, "invalid block or not an 'vk' block");
return NULL;
}
@@ -368,7 +368,7 @@ hivex_value_value (hive_h *h, hive_value_h value,
return ret;
} else {
if (!IS_VALID_BLOCK (h, data_offset) ||
- !BLOCK_ID_EQ (h, data_offset, "db")) {
+ !block_id_eq (h, data_offset, "db")) {
SET_ERRNO (EINVAL,
"declared data length is longer than the block and "
"block is not a db block (data 0x%zx, data len %zu)",
diff --git a/lib/write.c b/lib/write.c
index 0b25549..9de8ecd 100644
--- a/lib/write.c
+++ b/lib/write.c
@@ -340,7 +340,7 @@ insert_lf_record (hive_h *h, size_t old_offs, size_t posn,
/* Work around C stupidity.
*
http://www.redhat.com/archives/libguestfs/2010-February/msg00056.html
*/
- int test = BLOCK_ID_EQ (h, old_offs, "lf") || BLOCK_ID_EQ (h, old_offs,
"lh");
+ int test = block_id_eq (h, old_offs, "lf") || block_id_eq (h, old_offs,
"lh");
assert (test);
struct ntreg_lf_record *old_lf =
@@ -399,7 +399,7 @@ insert_li_record (hive_h *h, size_t old_offs, size_t posn,
const char *name, hive_node_h node)
{
assert (IS_VALID_BLOCK (h, old_offs));
- assert (BLOCK_ID_EQ (h, old_offs, "li"));
+ assert (block_id_eq (h, old_offs, "li"));
struct ntreg_ri_record *old_li =
(struct ntreg_ri_record *) ((char *) h->addr + old_offs);
@@ -452,7 +452,7 @@ static int
compare_name_with_nk_name (hive_h *h, const char *name, hive_node_h nk_offs)
{
assert (IS_VALID_BLOCK (h, nk_offs));
- assert (BLOCK_ID_EQ (h, nk_offs, "nk"));
+ assert (block_id_eq (h, nk_offs, "nk"));
/* Name in nk is not necessarily nul-terminated. */
char *nname = hivex_node_name (h, nk_offs);
@@ -493,7 +493,7 @@ insert_subkey (hive_h *h, const char *name,
* the end.
*/
for (i = 0; blocks[i] != 0; ++i) {
- if (BLOCK_ID_EQ (h, blocks[i], "lf") || BLOCK_ID_EQ (h, blocks[i],
"lh")) {
+ if (block_id_eq (h, blocks[i], "lf") || block_id_eq (h, blocks[i],
"lh")) {
old_offs = blocks[i];
old_lf = (struct ntreg_lf_record *) ((char *) h->addr + old_offs);
old_li = NULL;
@@ -504,7 +504,7 @@ insert_subkey (hive_h *h, const char *name,
goto insert_it;
}
}
- else if (BLOCK_ID_EQ (h, blocks[i], "li")) {
+ else if (block_id_eq (h, blocks[i], "li")) {
old_offs = blocks[i];
old_lf = NULL;
old_li = (struct ntreg_ri_record *) ((char *) h->addr + old_offs);
@@ -565,7 +565,7 @@ insert_subkey (hive_h *h, const char *name,
}
else {
for (i = 0; blocks[i] != 0; ++i) {
- if (BLOCK_ID_EQ (h, blocks[i], "ri")) {
+ if (block_id_eq (h, blocks[i], "ri")) {
struct ntreg_ri_record *ri =
(struct ntreg_ri_record *) ((char *) h->addr + blocks[i]);
for (j = 0; j < le16toh (ri->nr_offsets); ++j)
@@ -593,7 +593,7 @@ hivex_node_add_child (hive_h *h, hive_node_h parent, const char
*name)
{
CHECK_WRITABLE (0);
- if (!IS_VALID_BLOCK (h, parent) || !BLOCK_ID_EQ (h, parent, "nk")) {
+ if (!IS_VALID_BLOCK (h, parent) || !block_id_eq (h, parent, "nk")) {
SET_ERRNO (EINVAL, "invalid block or not an 'nk' block");
return 0;
}
@@ -649,7 +649,7 @@ hivex_node_add_child (hive_h *h, hive_node_h parent, const char
*name)
size_t parent_sk_offset = le32toh (parent_nk->sk);
parent_sk_offset += 0x1000;
if (!IS_VALID_BLOCK (h, parent_sk_offset) ||
- !BLOCK_ID_EQ (h, parent_sk_offset, "sk")) {
+ !block_id_eq (h, parent_sk_offset, "sk")) {
SET_ERRNO (EFAULT,
"parent sk is not a valid block (%zu)", parent_sk_offset);
return 0;
@@ -747,7 +747,7 @@ hivex_node_add_child (hive_h *h, hive_node_h parent, const char
*name)
static int
delete_sk (hive_h *h, size_t sk_offset)
{
- if (!IS_VALID_BLOCK (h, sk_offset) || !BLOCK_ID_EQ (h, sk_offset, "sk")) {
+ if (!IS_VALID_BLOCK (h, sk_offset) || !block_id_eq (h, sk_offset, "sk")) {
SET_ERRNO (EFAULT, "not an sk record: 0x%zx", sk_offset);
return -1;
}
@@ -852,7 +852,7 @@ hivex_node_delete_child (hive_h *h, hive_node_h node)
{
CHECK_WRITABLE (-1);
- if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
+ if (!IS_VALID_BLOCK (h, node) || !block_id_eq (h, node, "nk")) {
SET_ERRNO (EINVAL, "invalid block or not an 'nk' block");
return -1;
}
@@ -925,7 +925,7 @@ hivex_node_set_values (hive_h *h, hive_node_h node,
{
CHECK_WRITABLE (-1);
- if (!IS_VALID_BLOCK (h, node) || !BLOCK_ID_EQ (h, node, "nk")) {
+ if (!IS_VALID_BLOCK (h, node) || !block_id_eq (h, node, "nk")) {
SET_ERRNO (EINVAL, "invalid block or not an 'nk' block");
return -1;
}
--
2.0.2