aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--debian/libwireshark0.symbols2
-rw-r--r--epan/dissectors/packet-lat.c5
-rw-r--r--epan/dissectors/packet-quake.c48
-rw-r--r--epan/dissectors/packet-sccp.c3
-rw-r--r--epan/proto.c322
-rw-r--r--epan/proto.h26
-rw-r--r--epan/wslua/wslua_tree.c1
7 files changed, 348 insertions, 59 deletions
diff --git a/debian/libwireshark0.symbols b/debian/libwireshark0.symbols
index a55dfdd0cc..7ced7b4469 100644
--- a/debian/libwireshark0.symbols
+++ b/debian/libwireshark0.symbols
@@ -1055,7 +1055,9 @@ libwireshark.so.0 libwireshark0 #MINVER#
proto_tree_add_ipxnet_format_value@Base 1.9.1
proto_tree_add_item@Base 1.9.1
proto_tree_add_item_new@Base 1.12.0~rc1
+ proto_tree_add_item_new_ret_length@Base 2.1.0
proto_tree_add_item_ret_int@Base 1.99.6
+ proto_tree_add_item_ret_length@Base 2.1.0
proto_tree_add_item_ret_uint@Base 1.99.6
proto_tree_add_none_format@Base 1.9.1
proto_tree_add_protocol_format@Base 1.9.1
diff --git a/epan/dissectors/packet-lat.c b/epan/dissectors/packet-lat.c
index 37f1d6e7da..c812954075 100644
--- a/epan/dissectors/packet-lat.c
+++ b/epan/dissectors/packet-lat.c
@@ -333,9 +333,10 @@ static int
dissect_lat_string(tvbuff_t *tvb, int offset, int hf, proto_tree *tree)
{
proto_item *ti;
+ gint item_length;
- ti = proto_tree_add_item(tree, hf, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- return offset + proto_item_get_len(ti);
+ ti = proto_tree_add_item_ret_length(tree, hf, tvb, offset, 1, ENC_LITTLE_ENDIAN, &item_length);
+ return offset + item_length;
}
static guint
diff --git a/epan/dissectors/packet-quake.c b/epan/dissectors/packet-quake.c
index 448cda4e3f..a7bdc2c33f 100644
--- a/epan/dissectors/packet-quake.c
+++ b/epan/dissectors/packet-quake.c
@@ -153,13 +153,14 @@ dissect_quake_CCREQ_CONNECT
{
gint offset;
proto_item *ti;
+ gint item_len;
offset = 0;
if (tree) {
- ti = proto_tree_add_item(tree, hf_quake_CCREQ_CONNECT_game,
- tvb, offset, -1, ENC_ASCII|ENC_NA);
- offset += proto_item_get_len(ti);
+ ti = proto_tree_add_item_ret_length(tree, hf_quake_CCREQ_CONNECT_game,
+ tvb, offset, -1, ENC_ASCII|ENC_NA, &item_len);
+ offset += item_len;
proto_tree_add_item(tree, hf_quake_CCREQ_CONNECT_version,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
@@ -173,13 +174,14 @@ dissect_quake_CCREQ_SERVER_INFO
{
gint offset;
proto_item *ti;
+ gint item_len;
offset = 0;
if (tree) {
- ti = proto_tree_add_item(tree, hf_quake_CCREQ_SERVER_INFO_game,
- tvb, offset, -1, ENC_ASCII|ENC_NA);
- offset += proto_item_get_len(ti);
+ ti = proto_tree_add_item_ret_length(tree, hf_quake_CCREQ_SERVER_INFO_game,
+ tvb, offset, -1, ENC_ASCII|ENC_NA, &item_len);
+ offset += item_len;
proto_tree_add_item(tree, hf_quake_CCREQ_SERVER_INFO_version,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
}
@@ -243,23 +245,25 @@ dissect_quake_CCREP_SERVER_INFO
{
gint offset;
proto_item *ti;
+ gint item_len;
offset = 0;
if (tree) {
- ti = proto_tree_add_item(tree,
+ ti = proto_tree_add_item_ret_length(tree,
hf_quake_CCREP_SERVER_INFO_address, tvb, offset, -1,
- ENC_ASCII|ENC_NA);
- offset += proto_item_get_len(ti);
+ ENC_ASCII|ENC_NA, &item_len);
+ offset += item_len;
- ti = proto_tree_add_item(tree,
+ ti = proto_tree_add_item_ret_length(tree,
hf_quake_CCREP_SERVER_INFO_server, tvb, offset, -1,
- ENC_ASCII|ENC_NA);
- offset += proto_item_get_len(ti);
+ ENC_ASCII|ENC_NA, &item_len);
+ offset += item_len;
- ti = proto_tree_add_item(tree, hf_quake_CCREP_SERVER_INFO_map,
- tvb, offset, -1, ENC_ASCII|ENC_NA);
- offset += proto_item_get_len(ti);
+ ti = proto_tree_add_item_ret_length(tree,
+ hf_quake_CCREP_SERVER_INFO_map, tvb, offset, -1,
+ ENC_ASCII|ENC_NA, &item_len);
+ offset += item_len;
proto_tree_add_item(tree, hf_quake_CCREP_SERVER_INFO_num_player,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
@@ -284,6 +288,7 @@ dissect_quake_CCREP_PLAYER_INFO
guint32 color_pants;
proto_item *colors_item;
proto_tree *colors_tree;
+ gint item_len;
offset = 0;
@@ -292,9 +297,9 @@ dissect_quake_CCREP_PLAYER_INFO
tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
- ti = proto_tree_add_item(tree, hf_quake_CCREP_PLAYER_INFO_name,
- tvb, offset, -1, ENC_ASCII|ENC_NA);
- offset += proto_item_get_len(ti);
+ ti = proto_tree_add_item_ret_length(tree, hf_quake_CCREP_PLAYER_INFO_name,
+ tvb, offset, -1, ENC_ASCII|ENC_NA, &item_len);
+ offset += item_len;
colors = tvb_get_letohl(tvb, offset + 0);
color_shirt = (colors >> 4) & 0x0f;
@@ -331,15 +336,16 @@ dissect_quake_CCREP_RULE_INFO
{
gint offset;
proto_item *ti;
+ gint item_len;
if (tvb_reported_length(tvb) == 0) return;
offset = 0;
if (tree) {
- ti = proto_tree_add_item(tree, hf_quake_CCREP_RULE_INFO_rule,
- tvb, offset, -1, ENC_ASCII|ENC_NA);
- offset += proto_item_get_len(ti);
+ ti = proto_tree_add_item_ret_length(tree, hf_quake_CCREP_RULE_INFO_rule,
+ tvb, offset, -1, ENC_ASCII|ENC_NA, &item_len);
+ offset += item_len;
proto_tree_add_item(tree, hf_quake_CCREP_RULE_INFO_value,
tvb, offset, -1, ENC_ASCII|ENC_NA);
diff --git a/epan/dissectors/packet-sccp.c b/epan/dissectors/packet-sccp.c
index c1a8567985..6fc8b3e3e2 100644
--- a/epan/dissectors/packet-sccp.c
+++ b/epan/dissectors/packet-sccp.c
@@ -2562,6 +2562,9 @@ dissect_sccp_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree,
/* sccp_length = proto_item_get_len(sccp_item);
* sccp_length -= parameter_length;
* proto_item_set_len(sccp_item, sccp_length);
+ *
+ * except that proto_item_get_len() is *NOT* guaranteed to return
+ * a correct value - if the item has been "faked", it will be wrong
*/
break;
diff --git a/epan/proto.c b/epan/proto.c
index be54c4b84c..3a9566a9ba 100644
--- a/epan/proto.c
+++ b/epan/proto.c
@@ -82,6 +82,23 @@ struct ptvcursor {
/** See inlined comments.
@param tree the tree to append this item to
+ @param free_block a code block to call to free resources if this returns
+ @return NULL if 'tree' is null */
+#define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block) \
+ if (!tree) { \
+ free_block; \
+ return NULL; \
+ }
+
+/** See inlined comments.
+ @param tree the tree to append this item to
+ @param free_block a code block to call to free resources if this returns
+ @return NULL if 'tree' is null */
+#define CHECK_FOR_NULL_TREE(tree) \
+ CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))
+
+/** See inlined comments.
+ @param tree the tree to append this item to
@param hfindex field index
@param hfinfo header_field
@param free_block a code block to call to free resources if this returns
@@ -98,10 +115,6 @@ struct ptvcursor {
We fake FT_PROTOCOL unless some clients have requested us \
not to do so. \
*/ \
- if (!tree) { \
- free_block; \
- return NULL; \
- } \
PTREE_DATA(tree)->count++; \
if (PTREE_DATA(tree)->count > MAX_TREE_ITEMS) { \
free_block; \
@@ -181,6 +194,10 @@ static void
get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
gint *item_length);
+static gint
+get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
+ gint length, guint item_length, const gint encoding);
+
static field_info *
new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
const gint start, const gint item_length);
@@ -1118,6 +1135,8 @@ ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, gint length,
tree = ptvcursor_tree(ptvc);
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
@@ -1155,6 +1174,8 @@ proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, gint start, gint l
va_list ap;
header_field_info *hfinfo;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
pi = proto_tree_add_text_node(tree, tvb, start, length);
@@ -1176,6 +1197,8 @@ proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, gint start,
proto_item *pi;
header_field_info *hfinfo;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
pi = proto_tree_add_text_node(tree, tvb, start, length);
@@ -1246,6 +1269,8 @@ proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint len
proto_item *pi;
header_field_info *hfinfo;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
pi = proto_tree_add_text_node(tree, tvb, start, length);
@@ -1263,6 +1288,8 @@ proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint
proto_item *pi;
header_field_info *hfinfo;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
pi = proto_tree_add_text_node(tree, tvb, start, length);
@@ -1982,7 +2009,7 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree,
break;
case FT_STRINGZ:
- if (length < -1 ) {
+ if (length < -1) {
report_type_length_mismatch(tree, "a string", length, TRUE);
}
/* Instead of calling proto_item_set_len(),
@@ -2209,13 +2236,12 @@ gint32 *retval)
if (retval)
*retval = value;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
new_fi = new_field_info(tree, hfinfo, tvb, start, length);
- if (new_fi == NULL)
- return NULL;
-
proto_tree_set_int(new_fi, value);
FI_SET_FLAG(new_fi,
@@ -2226,8 +2252,8 @@ gint32 *retval)
proto_item *
proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
-const gint start, gint length, const guint encoding,
-guint32 *retval)
+ const gint start, gint length,
+ const guint encoding, guint32 *retval)
{
header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
field_info *new_fi;
@@ -2261,13 +2287,12 @@ guint32 *retval)
if (retval)
*retval = value;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
new_fi = new_field_info(tree, hfinfo, tvb, start, length);
- if (new_fi == NULL)
- return NULL;
-
proto_tree_set_uint(new_fi, value);
FI_SET_FLAG(new_fi,
@@ -2310,25 +2335,24 @@ ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length,
field_info *new_fi;
header_field_info *hfinfo;
gint item_length;
- guint32 n;
int offset;
- /* We can't fake it just yet. We have to advance the cursor
- TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo); */
-
offset = ptvc->offset;
PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length);
- ptvc->offset += length;
- if (hfinfo->type == FT_UINT_BYTES || hfinfo->type == FT_UINT_STRING) {
- /*
- * The length of the rest of the item is in the first N
- * bytes of the item.
- */
- n = get_uint_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
- ptvc->offset += n;
+
+ if (!ptvc->tree) {
+ ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset,
+ length, item_length, encoding);
+ return NULL;
}
+ offset = ptvc->offset;
+ PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
+ get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length);
+ ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
+ item_length, encoding);
+
test_length(hfinfo, ptvc->tvb, offset, item_length);
/* Coast clear. Try and fake it */
@@ -2344,7 +2368,7 @@ ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length,
the item is extracted from the tvbuff handed to it. */
proto_item *
proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
- const gint start, gint length, const guint encoding)
+ const gint start, gint length, const guint encoding)
{
field_info *new_fi;
gint item_length;
@@ -2354,13 +2378,12 @@ proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *t
get_hfi_length(hfinfo, tvb, start, &length, &item_length);
test_length(hfinfo, tvb, start, item_length);
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
- if (new_fi == NULL)
- return NULL;
-
return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
}
@@ -2374,6 +2397,56 @@ proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
}
+/* Add an item to a proto_tree, using the text label registered to that item;
+ the item is extracted from the tvbuff handed to it.
+
+ Return the length of the item through the pointer. */
+proto_item *
+proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
+ tvbuff_t *tvb, const gint start,
+ gint length, const guint encoding,
+ gint *retval)
+{
+ field_info *new_fi;
+ gint item_length;
+ proto_item *item;
+
+ DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
+
+ get_hfi_length(hfinfo, tvb, start, &length, &item_length);
+ test_length(hfinfo, tvb, start, item_length);
+
+ if (!tree) {
+ /*
+ * We need to get the correct item length here.
+ * That's normally done by proto_tree_new_item(),
+ * but we won't be calling it.
+ */
+ *retval = get_full_length(hfinfo, tvb, start, length,
+ item_length, encoding);
+ return NULL;
+ }
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
+
+ new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
+
+ item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
+ *retval = new_fi->length;
+ return item;
+}
+
+proto_item *
+proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
+ const gint start, gint length,
+ const guint encoding, gint *retval)
+{
+ register header_field_info *hfinfo;
+
+ PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
+ return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, retval);
+}
+
/* which FT_ types can use proto_tree_add_bytes_item() */
static inline gboolean
validate_proto_tree_add_bytes_ftype(const enum ftenum type)
@@ -2465,6 +2538,14 @@ proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
if (err) *err = saved_err;
+ CHECK_FOR_NULL_TREE_AND_FREE(tree,
+ {
+ if (created_bytes)
+ g_byte_array_free(created_bytes, TRUE);
+ created_bytes = NULL;
+ bytes = NULL;
+ } );
+
TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo,
{
if (created_bytes)
@@ -2476,9 +2557,6 @@ proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
/* n will be zero except when it's a FT_UINT_BYTES */
new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
- if (new_fi == NULL)
- return NULL;
-
if (encoding & ENC_STRING) {
if (saved_err == ERANGE)
expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
@@ -2558,13 +2636,12 @@ proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
retval->nsecs = time_stamp.nsecs;
}
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
new_fi = new_field_info(tree, hfinfo, tvb, start, length);
- if (new_fi == NULL)
- return NULL;
-
proto_tree_set_time(new_fi, &time_stamp);
if (encoding & ENC_STRING) {
@@ -2591,6 +2668,8 @@ proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
va_list ap;
header_field_info *hfinfo;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_NONE);
@@ -2645,6 +2724,8 @@ proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
va_list ap;
header_field_info *hfinfo;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL);
@@ -2675,6 +2756,8 @@ proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
get_hfi_length(hfinfo, tvb, start, &length, &item_length);
test_length(hfinfo, tvb, start, item_length);
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
@@ -2698,6 +2781,8 @@ proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, g
get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length);
test_length(hfinfo, tvb, start, item_length);
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
@@ -2723,6 +2808,8 @@ proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
get_hfi_length(hfinfo, tvb, start, &length, &item_length);
test_length(hfinfo, tvb, start, item_length);
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
if (start_ptr)
@@ -2753,6 +2840,8 @@ proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
get_hfi_length(hfinfo, tvb, start, &length, &item_length);
test_length(hfinfo, tvb, start, item_length);
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
if (start_ptr)
@@ -2812,6 +2901,8 @@ proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
proto_item *pi;
header_field_info *hfinfo;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
@@ -2877,6 +2968,8 @@ proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
proto_item *pi;
header_field_info *hfinfo;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPXNET);
@@ -2940,6 +3033,8 @@ proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
proto_item *pi;
header_field_info *hfinfo;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv4);
@@ -3003,6 +3098,8 @@ proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
proto_item *pi;
header_field_info *hfinfo;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv6);
@@ -3089,6 +3186,8 @@ proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
proto_item *pi;
header_field_info *hfinfo;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_GUID);
@@ -3164,6 +3263,8 @@ proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
proto_item *pi;
header_field_info *hfinfo;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_OID);
@@ -3264,6 +3365,8 @@ proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
proto_item *pi;
header_field_info *hfinfo;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT_FIELD_TYPE_IS_STRING(hfinfo);
@@ -3421,6 +3524,8 @@ proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
proto_item *pi;
header_field_info *hfinfo;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_ETHER);
@@ -3490,6 +3595,8 @@ proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
proto_item *pi;
header_field_info *hfinfo;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
@@ -3545,6 +3652,8 @@ proto_tree_add_boolean64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint star
proto_item *pi;
header_field_info *hfinfo;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
@@ -3616,6 +3725,8 @@ proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
proto_item *pi;
header_field_info *hfinfo;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_FLOAT);
@@ -3679,6 +3790,8 @@ proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
proto_item *pi;
header_field_info *hfinfo;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_DOUBLE);
@@ -3742,6 +3855,8 @@ proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
proto_item *pi = NULL;
header_field_info *hfinfo;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
switch (hfinfo->type) {
@@ -3828,6 +3943,8 @@ proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
proto_item *pi = NULL;
header_field_info *hfinfo;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
switch (hfinfo->type) {
@@ -3918,6 +4035,8 @@ proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
proto_item *pi = NULL;
header_field_info *hfinfo;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
switch (hfinfo->type) {
@@ -4007,6 +4126,8 @@ proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
proto_item *pi = NULL;
header_field_info *hfinfo;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
switch (hfinfo->type) {
@@ -4096,6 +4217,8 @@ proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
proto_item *pi;
header_field_info *hfinfo;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_EUI64);
@@ -4352,6 +4475,113 @@ get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint
}
}
+static gint
+get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
+ gint length, guint item_length, const gint encoding)
+{
+ guint32 n;
+
+ /*
+ * We need to get the correct item length here.
+ * That's normally done by proto_tree_new_item(),
+ * but we won't be calling it.
+ */
+ switch (hfinfo->type) {
+
+ case FT_NONE:
+ case FT_PROTOCOL:
+ case FT_BYTES:
+ /*
+ * The length is the specified length.
+ */
+ break;
+
+ case FT_UINT_BYTES:
+ /*
+ * Map all non-zero values to little-endian for
+ * backwards compatibility.
+ */
+ n = get_uint_value(NULL, tvb, start, length,
+ encoding ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN);
+ item_length += n;
+ break;
+
+ case FT_BOOLEAN:
+ /* XXX - make these just FT_UINT? */
+ case FT_UINT8:
+ case FT_UINT16:
+ case FT_UINT24:
+ case FT_UINT32:
+ case FT_UINT40:
+ case FT_UINT48:
+ case FT_UINT56:
+ case FT_UINT64:
+ /* XXX - make these just FT_INT? */
+ case FT_INT8:
+ case FT_INT16:
+ case FT_INT24:
+ case FT_INT32:
+ case FT_INT40:
+ case FT_INT48:
+ case FT_INT56:
+ case FT_INT64:
+ case FT_IPv4:
+ case FT_IPXNET:
+ case FT_IPv6:
+ case FT_FCWWN:
+ case FT_AX25:
+ case FT_VINES:
+ case FT_ETHER:
+ case FT_EUI64:
+ case FT_GUID:
+ case FT_OID:
+ case FT_REL_OID:
+ case FT_SYSTEM_ID:
+ case FT_FLOAT:
+ case FT_DOUBLE:
+ case FT_STRING:
+ /*
+ * The length is the specified length.
+ */
+ break;
+
+ case FT_STRINGZ:
+ if (length < -1) {
+ report_type_length_mismatch(NULL, "a string", length, TRUE);
+ }
+ if (length == -1) {
+ /* This can throw an exception */
+ /* XXX - do this without fetching the string? */
+ tvb_get_stringz_enc(wmem_packet_scope(), tvb, start, &length, encoding);
+ }
+ item_length = length;
+ break;
+
+ case FT_UINT_STRING:
+ n = get_uint_value(NULL, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
+ item_length += n;
+ break;
+
+ case FT_STRINGZPAD:
+ case FT_ABSOLUTE_TIME:
+ case FT_RELATIVE_TIME:
+ case FT_IEEE_11073_SFLOAT:
+ case FT_IEEE_11073_FLOAT:
+ /*
+ * The length is the specified length.
+ */
+ break;
+
+ default:
+ g_error("hfinfo->type %d (%s) not handled\n",
+ hfinfo->type,
+ ftype_name(hfinfo->type));
+ DISSECTOR_ASSERT_NOT_REACHED();
+ break;
+ }
+ return item_length;
+}
+
static field_info *
new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
const gint start, const gint item_length)
@@ -8890,6 +9120,7 @@ proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
* but only after doing a bunch more work (which we can, in the common
* case, shortcut here).
*/
+ CHECK_FOR_NULL_TREE(tree);
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL, encoding);
@@ -8968,6 +9199,7 @@ _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
}
/* Coast clear. Try and fake it */
+ CHECK_FOR_NULL_TREE(tree);
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
bf_str = decode_bits_in_field(bit_offset, no_of_bits, value);
@@ -9120,6 +9352,7 @@ proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbu
}
/* Coast clear. Try and fake it */
+ CHECK_FOR_NULL_TREE(tree);
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
/* initialise the format string */
@@ -9244,6 +9477,7 @@ _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
header_field_info *hf_field;
/* We do not have to return a value, try to fake it as soon as possible */
+ CHECK_FOR_NULL_TREE(tree);
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
if (hf_field->bitmask != 0) {
@@ -9368,6 +9602,8 @@ proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
gchar *dst;
header_field_info *hf_field;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
switch (hf_field->type) {
@@ -9398,6 +9634,8 @@ proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
gchar *dst;
header_field_info *hf_field;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
switch (hf_field->type) {
@@ -9428,6 +9666,8 @@ proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
gchar *dst;
header_field_info *hf_field;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_FLOAT);
@@ -9447,6 +9687,8 @@ proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
gchar *dst;
header_field_info *hf_field;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
switch (hf_field->type) {
@@ -9477,6 +9719,8 @@ proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
gchar *dst;
header_field_info *hf_field;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
switch (hf_field->type) {
@@ -9507,6 +9751,8 @@ proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
gchar *dst;
header_field_info *hf_field;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_BOOLEAN);
@@ -9526,6 +9772,8 @@ proto_tree_add_boolean_bits_format_value64(proto_tree *tree, const int hfindex,
gchar *dst;
header_field_info *hf_field;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
DISSECTOR_ASSERT(hf_field->type == FT_BOOLEAN);
@@ -9545,6 +9793,8 @@ proto_tree_add_ts_23_038_7bits_item(proto_tree *tree, const int hfindex, tvbuff_
gint byte_offset;
gchar *string;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
@@ -9575,6 +9825,8 @@ proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *t
gint byte_offset;
gchar *string;
+ CHECK_FOR_NULL_TREE(tree);
+
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
diff --git a/epan/proto.h b/epan/proto.h
index 51e4dc0bac..0b35a9ce54 100644
--- a/epan/proto.h
+++ b/epan/proto.h
@@ -1003,6 +1003,27 @@ proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
const gint start, gint length, const guint encoding);
/** Add an item to a proto_tree, using the text label registered to that item.
+ The item is extracted from the tvbuff handed to it.
+
+ Return the length of the item through the pointer.
+ @param tree the tree to append this item to
+ @param hfinfo field
+ @param tvb the tv buffer of the current data
+ @param start start of data in tvb
+ @param length length of data in tvb
+ @param encoding data encoding
+ @param retval pointer to variable to set to the item length
+ @return the newly created item */
+WS_DLL_PUBLIC proto_item *
+proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
+ const gint start, gint length, const guint encoding, gint *retval);
+
+WS_DLL_PUBLIC proto_item *
+proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
+ const gint start, gint length,
+ const guint encoding, gint *retval);
+
+/** Add an item to a proto_tree, using the text label registered to that item.
The item is extracted from the tvbuff handed to it, and the retrieved
value is also set to *retval so the caller gets it back for other uses.
@@ -1019,7 +1040,7 @@ encoding in the tvbuff
The length argument must
be set to the appropriate size of the native type as in other proto_add routines.
-Integers of 8, 16, 24 and 32 bits can be retreived with these functions.
+Integers of 8, 16, 24 and 32 bits can be retrieved with these functions.
@param tree the tree to append this item to
@param hfindex field
@@ -2735,6 +2756,9 @@ proto_custom_set(proto_tree* tree, GSList *field_id,
#define proto_tree_add_item(tree, hfinfo, tvb, start, length, encoding) \
proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding)
+#define proto_tree_add_item_ret_length(tree, hfinfo, tvb, start, length, encoding, retval) \
+ proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, retval)
+
#define proto_tree_add_boolean(tree, hfinfo, tvb, start, length, value) \
proto_tree_add_boolean(tree, (hfinfo)->id, tvb, start, length, value)
diff --git a/epan/wslua/wslua_tree.c b/epan/wslua/wslua_tree.c
index a002d2708e..66ae4869ef 100644
--- a/epan/wslua/wslua_tree.c
+++ b/epan/wslua/wslua_tree.c
@@ -801,6 +801,7 @@ static int TreeItem_get_len(lua_State* L) {
TreeItem ti = checkTreeItem(L,1);
int len = 0;
+ /* XXX - this is *NOT* guaranteed to return a correct value! */
len = proto_item_get_len(ti->item);
lua_pushinteger(L, len > 0 ? len : 0);