diff options
-rw-r--r-- | debian/libwireshark0.symbols | 2 | ||||
-rw-r--r-- | epan/dissectors/packet-lat.c | 5 | ||||
-rw-r--r-- | epan/dissectors/packet-quake.c | 48 | ||||
-rw-r--r-- | epan/dissectors/packet-sccp.c | 3 | ||||
-rw-r--r-- | epan/proto.c | 322 | ||||
-rw-r--r-- | epan/proto.h | 26 | ||||
-rw-r--r-- | epan/wslua/wslua_tree.c | 1 |
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); |