aboutsummaryrefslogtreecommitdiffstats
path: root/epan/proto.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2003-06-04 21:51:54 +0000
committerGuy Harris <guy@alum.mit.edu>2003-06-04 21:51:54 +0000
commitaa1c605ba30bd15f357cbbc3d9c2df4064d92286 (patch)
tree8f7a1d61efccb26b7ac1284c7ed60e5faa229ee2 /epan/proto.c
parentdd6f38957b5fcb138c34d094e4070330e22d20c1 (diff)
When "proto_tree_add_item()" is used with an FT_STRINGZ and given a
length (rather than being given -1), the length is, in most cases, the maximum length of a null-*padded* string, rather than the actual length of a null-*terminated* string. Treat it as such - allocate a buffer one larger than the length (to leave room for a terminating '\0'), and pass the size of that buffer to "tvb_get_nstringz0()". (Otherwise, in those cases, the last character of the string is chopped off.) Allow "proto_tree_add_string()" to add FT_STRINGZ items to the protocol tree, as well as FT_STRING items. In "alloc_field_info()", if we're passed a length of -1 and the field is an FT_STRINGZ, don't make the length be the length remaining in the tvbuff; that way, you *can* use a length of -1 in "proto_tree_add_item()" for an FT_STRINGZ item, and have it get the actual length by looking for the terminating '\0'. (We might want to distinguish between null-terminated and null-padded strings, e.g. with an FT_STRINGZPAD type. Null-terminated strings rarely, if ever, have a specified length; the length is found by scanning for the terminating '\0'. Null-padded strings presumably always have a specified length, which is the length to which the string is padded.) svn path=/trunk/; revision=7784
Diffstat (limited to 'epan/proto.c')
-rw-r--r--epan/proto.c91
1 files changed, 67 insertions, 24 deletions
diff --git a/epan/proto.c b/epan/proto.c
index 4738c6de48..802dd2225b 100644
--- a/epan/proto.c
+++ b/epan/proto.c
@@ -1,7 +1,7 @@
/* proto.c
* Routines for protocol tree
*
- * $Id: proto.c,v 1.86 2003/05/19 03:23:12 gerald Exp $
+ * $Id: proto.c,v 1.87 2003/06/04 21:51:54 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -699,6 +699,15 @@ proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
case FT_STRINGZ:
if (length != 0) { /* XXX - Should we throw an exception instead? */
+ /* Instead of calling proto_item_set_len(),
+ * since we don't yet have a proto_item, we
+ * set the field_info's length ourselves.
+ *
+ * XXX - our caller can't use that length to
+ * advance an offset unless they arrange that
+ * there always be a protocol tree into which
+ * we're putting this item.
+ */
if (length == -1) {
/* This can throw an exception */
length = tvb_strsize(tvb, start);
@@ -710,14 +719,23 @@ proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
new_fi->length = length;
}
else {
- /* In this case, length signifies maximum length. */
-
- /* This g_strdup'ed memory is freed in proto_tree_free_node() */
- string = g_malloc(length);
+ /* In this case, length signifies
+ * maximum length. That does not
+ * include the trailing '\0'; we
+ * assume this is null-padded,
+ * not null-terminated, so we need
+ * a buffer of length length+1,
+ * with the extra 1 for the trailing
+ * '\0'. */
+
+ /* This g_strdup'ed memory is freed
+ * in proto_tree_free_node() */
+ string = g_malloc(length + 1);
CLEANUP_PUSH(g_free, string);
- found_length = tvb_get_nstringz0(tvb, start, length, string);
+ found_length = tvb_get_nstringz0(tvb,
+ start, length + 1, string);
CLEANUP_POP;
new_fi->length = found_length + 1;
@@ -731,17 +749,24 @@ proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
n = get_uint_value(tvb, start, length, little_endian);
proto_tree_set_string_tvb(new_fi, tvb, start + length, n);
- /* Instead of calling proto_item_set_len(), since we don't yet
- * have a proto_item, we set the field_info's length ourselves. */
+ /* Instead of calling proto_item_set_len(), since we
+ * don't yet have a proto_item, we set the
+ * field_info's length ourselves.
+ *
+ * XXX - our caller can't use that length to
+ * advance an offset unless they arrange that
+ * there always be a protocol tree into which
+ * we're putting this item.
+ */
new_fi->length = n + length;
break;
+
default:
g_error("new_fi->hfinfo->type %d (%s) not handled\n",
new_fi->hfinfo->type,
ftype_name(new_fi->hfinfo->type));
g_assert_not_reached();
break;
-
}
/* Don't add new node to proto_tree until now so that any exceptions
@@ -750,13 +775,13 @@ proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
CLEANUP_POP;
- /* If the proto_tree wants to keep a record of this finfo
- * for quick lookup, then record it. */
- hash = PTREE_DATA(tree)->interesting_hfids;
- ptrs = g_hash_table_lookup(hash, GINT_TO_POINTER(hfindex));
- if (ptrs) {
- g_ptr_array_add(ptrs, new_fi);
- }
+ /* If the proto_tree wants to keep a record of this finfo
+ * for quick lookup, then record it. */
+ hash = PTREE_DATA(tree)->interesting_hfids;
+ ptrs = g_hash_table_lookup(hash, GINT_TO_POINTER(hfindex));
+ if (ptrs) {
+ g_ptr_array_add(ptrs, new_fi);
+ }
return pi;
}
@@ -1199,7 +1224,7 @@ proto_tree_set_uint64_tvb(field_info *fi, tvbuff_t *tvb, gint start, gboolean li
proto_tree_set_uint64(fi, tvb_get_ptr(tvb, start, 8), little_endian);
}
-/* Add a FT_STRING to a proto_tree. Creates own copy of string,
+/* Add a FT_STRING or FT_STRINGZ to a proto_tree. Creates own copy of string,
* and frees it when the proto_tree is destroyed. */
proto_item *
proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
@@ -1213,7 +1238,7 @@ proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
return (NULL);
hfinfo = proto_registrar_get_nth(hfindex);
- g_assert(hfinfo->type == FT_STRING);
+ g_assert(hfinfo->type == FT_STRING || hfinfo->type == FT_STRINGZ);
pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
proto_tree_set_string(new_fi, value, FALSE);
@@ -1828,14 +1853,32 @@ alloc_field_info(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
* that, if we throw an exception while dissecting, it
* has what is probably the right value.
*
+ * For FT_STRINGZ, it means "the string is null-terminated,
+ * not null-padded; set the length to the actual length
+ * of the string", and if the tvbuff if short, we just
+ * throw an exception.
+ *
* It's not valid for any other type of field.
*/
- g_assert(hfinfo->type == FT_PROTOCOL ||
- hfinfo->type == FT_NONE ||
- hfinfo->type == FT_BYTES ||
- hfinfo->type == FT_STRING ||
- hfinfo->type == FT_STRINGZ);
- *length = tvb_ensure_length_remaining(tvb, start);
+ switch (hfinfo->type) {
+
+ case FT_PROTOCOL:
+ case FT_NONE:
+ case FT_BYTES:
+ case FT_STRING:
+ *length = tvb_ensure_length_remaining(tvb, start);
+ break;
+
+ case FT_STRINGZ:
+ /*
+ * Leave the length as -1, so our caller knows
+ * it was -1.
+ */
+ break;
+
+ default:
+ g_assert_not_reached();
+ }
}
fi = g_mem_chunk_alloc(gmc_field_info);