diff --git a/epan/proto.c b/epan/proto.c index 004acb0..bf98a27 100644 --- a/epan/proto.c +++ b/epan/proto.c @@ -1758,6 +1758,31 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree, return pi; } + +/* + * Validates that field length bytes are available starting from + * start (pos/neg). Throws an exception if they aren't. + */ +static void +test_length(header_field_info *hfinfo, tvbuff_t *tvb, + gint start, gint length) +{ + gint size = length; + + if (!tvb) + return; + + if (hfinfo->type == FT_STRINGZ) { + /* If we're fetching until the end of the TVB, only validate + * that the offset is within range. + */ + if (length == -1) + size = 0; + } + + tvb_ensure_bytes_exist(tvb, start, size); +} + /* Gets data from tvbuff, adds it to proto_tree, increments offset, and returns proto_item* */ proto_item * @@ -1786,6 +1811,8 @@ ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length, ptvc->offset += n; } + test_length(hfinfo, ptvc->tvb, offset, item_length); + /* Coast clear. Try and fake it */ TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo); @@ -1795,45 +1822,6 @@ ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length, offset, length, encoding); } -/* - * Validates that field length bytes are available starting from - * start (pos/neg). Throws an exception if they aren't. - */ -static void -test_length(header_field_info *hfinfo, proto_tree *tree, tvbuff_t *tvb, - gint start, gint length, const guint encoding) -{ - gint size = length; - - if (!tvb) - return; - - if (hfinfo->type == FT_UINT_BYTES || hfinfo->type == FT_UINT_STRING) { - guint32 n; - - n = get_uint_value(tree, tvb, start, length, encoding); - if (n > size + n) { - /* If n > size + n then we have an integer overflow, so - * set size to -1, which will force the - * tvb_ensure_bytes_exist call below to throw a - * ReportedBoundsError - */ - size = -1; - } - else { - size += n; - } - } else if (hfinfo->type == FT_STRINGZ) { - /* If we're fetching until the end of the TVB, only validate - * that the offset is within range. - */ - if (length == -1) - size = 0; - } - - tvb_ensure_bytes_exist(tvb, start, size); -} - /* 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. */ proto_item * @@ -1845,7 +1833,7 @@ proto_tree_add_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb, gint item_length; hfinfo = get_hfi_and_length(hfindex, tvb, start, &length, &item_length); - test_length(hfinfo, tree, tvb, start, item_length, encoding); + test_length(hfinfo, tvb, start, item_length); TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo); @@ -7540,7 +7528,7 @@ proto_tree_add_bits_item(proto_tree *tree, const int hf_index, tvbuff_t *tvb, octet_length = (no_of_bits + 7) >> 3; octet_offset = bit_offset >> 3; - test_length(hfinfo, tree, tvb, octet_offset, octet_length, encoding); + test_length(hfinfo, tvb, octet_offset, octet_length); /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val() * but only after doing a bunch more work (which we can, in the common