aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvan Huus <eapache@gmail.com>2013-10-17 12:24:25 +0000
committerEvan Huus <eapache@gmail.com>2013-10-17 12:24:25 +0000
commitcbe8af0a8b75399f3fe909ee8b838eeedd6fae40 (patch)
treef4c94c87c5cfc34faa14769b5a41908918c6db2a
parent744f47107e28a8632cf79fde901713f73fd0e349 (diff)
Revert the optimization in r52578. As Jakub predicted, it caused at least one
infinite loop to pop up. We're just going to have to eat the performance hit. (https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=9282) svn path=/trunk/; revision=52660
-rw-r--r--epan/proto.c52
-rw-r--r--epan/tvbuff.c15
-rw-r--r--epan/tvbuff.h3
3 files changed, 44 insertions, 26 deletions
diff --git a/epan/proto.c b/epan/proto.c
index 46039b1425..28d83ed1d5 100644
--- a/epan/proto.c
+++ b/epan/proto.c
@@ -1750,6 +1750,45 @@ 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 *
@@ -1761,13 +1800,11 @@ proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *t
DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
- if (tvb) {
- tvb_ensure_offset_exists(tvb, start);
- }
+ get_hfi_length(hfinfo, tvb, start, &length, &item_length);
+ test_length(hfinfo, tree, tvb, start, item_length, encoding);
TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
- get_hfi_length(hfinfo, tvb, start, &length, &item_length);
new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
if (new_fi == NULL)
@@ -6959,15 +6996,14 @@ proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
const guint encoding)
{
header_field_info *hfinfo;
+ gint octet_length;
gint octet_offset;
PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
+ octet_length = (no_of_bits + 7) >> 3;
octet_offset = bit_offset >> 3;
-
- if (tvb) {
- tvb_ensure_offset_exists(tvb, octet_offset);
- }
+ test_length(hfinfo, tree, tvb, octet_offset, octet_length, encoding);
/* 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
diff --git a/epan/tvbuff.c b/epan/tvbuff.c
index b967e81f11..e783746acd 100644
--- a/epan/tvbuff.c
+++ b/epan/tvbuff.c
@@ -510,21 +510,6 @@ tvb_offset_exists(const tvbuff_t *tvb, const gint offset)
}
}
-/* Like tvb_offset_exists except it throws an exception instead of returning
- * FALSE */
-void
-tvb_ensure_offset_exists(const tvbuff_t *tvb, const gint offset)
-{
- guint abs_offset;
- int exception;
-
- DISSECTOR_ASSERT(tvb && tvb->initialized);
-
- exception = compute_offset(tvb, offset, &abs_offset);
- if (exception)
- THROW(exception);
-}
-
guint
tvb_reported_length(const tvbuff_t *tvb)
{
diff --git a/epan/tvbuff.h b/epan/tvbuff.h
index d31da15e98..7fef12da6b 100644
--- a/epan/tvbuff.h
+++ b/epan/tvbuff.h
@@ -239,9 +239,6 @@ WS_DLL_PUBLIC void tvb_ensure_bytes_exist(const tvbuff_t *tvb, const gint offset
/* Checks (w/o throwing exception) that offset exists in buffer */
WS_DLL_PUBLIC gboolean tvb_offset_exists(const tvbuff_t*, const gint offset);
-/* Checks that offset exists in buffer and throws an exception if it doesn't */
-WS_DLL_PUBLIC void tvb_ensure_offset_exists(const tvbuff_t*, const gint offset);
-
/* Get reported length of buffer */
WS_DLL_PUBLIC guint tvb_reported_length(const tvbuff_t*);