aboutsummaryrefslogtreecommitdiffstats
path: root/epan/tvbuff_subset.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2018-04-19 20:18:10 -0700
committerGuy Harris <guy@alum.mit.edu>2018-04-20 03:18:47 +0000
commit0a130c5756eda79cbb55f1d38824fbaf9d1abc68 (patch)
treefb3188f1965219c227e82fb5fcb7cc5307a5e1fc /epan/tvbuff_subset.c
parent9011a25afc598bfb5d46be92b2ef112cd1b17594 (diff)
Handle subset tvbuffs where the length goes past the end of the parent.
Add a "contained length" to tvbuffs. For non-subset tvbuffs, that's the same as the reported length. For a subset tvbuff, that's the amount of the reported data that was actually present in the "contained data" of the parent tvbuff. This is unaffected by the *captured* length of any tvbuff; that differs from the contained length only if the capture was cut short by a snapshot length. If a reference is within the reported data, but not within the contained data, a ContainedBoundsError exception is thrown. This exception represents a protocol error, rather than a reference past the captured data in the packet; we treat it as such. Change-Id: Ide87f81238eaeb89b3093f54a87bf7f715485af5 Reviewed-on: https://code.wireshark.org/review/27039 Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'epan/tvbuff_subset.c')
-rw-r--r--epan/tvbuff_subset.c33
1 files changed, 22 insertions, 11 deletions
diff --git a/epan/tvbuff_subset.c b/epan/tvbuff_subset.c
index 518d573bc5..8a33147480 100644
--- a/epan/tvbuff_subset.c
+++ b/epan/tvbuff_subset.c
@@ -95,7 +95,7 @@ static const struct tvb_ops tvb_subset_ops = {
};
static tvbuff_t *
-tvb_new_with_subset(tvbuff_t *backing, const gint reported_length,
+tvb_new_with_subset(tvbuff_t *backing, const guint reported_length,
const guint subset_tvb_offset, const guint subset_tvb_length)
{
tvbuff_t *tvb = tvb_new(&tvb_subset_ops);
@@ -106,14 +106,14 @@ tvb_new_with_subset(tvbuff_t *backing, const gint reported_length,
subset_tvb->subset.tvb = backing;
tvb->length = subset_tvb_length;
+ /*
+ * The contained length must not exceed what remains in the
+ * backing tvbuff.
+ */
+ tvb->contained_length = MIN(reported_length, backing->contained_length - subset_tvb_offset);
tvb->flags = backing->flags;
- if (reported_length == -1) {
- tvb->reported_length = backing->reported_length - subset_tvb_offset;
- }
- else {
- tvb->reported_length = reported_length;
- }
+ tvb->reported_length = reported_length;
tvb->initialized = TRUE;
/* Optimization. If the backing buffer has a pointer to contiguous, real data,
@@ -137,6 +137,7 @@ tvb_new_subset_length_caplen(tvbuff_t *backing, const gint backing_offset, const
tvbuff_t *tvb;
guint subset_tvb_offset;
guint subset_tvb_length;
+ guint actual_reported_length;
DISSECTOR_ASSERT(backing && backing->initialized);
@@ -146,7 +147,12 @@ tvb_new_subset_length_caplen(tvbuff_t *backing, const gint backing_offset, const
&subset_tvb_offset,
&subset_tvb_length);
- tvb = tvb_new_with_subset(backing, reported_length,
+ if (reported_length == -1)
+ actual_reported_length = backing->reported_length - subset_tvb_offset;
+ else
+ actual_reported_length = (guint)reported_length;
+
+ tvb = tvb_new_with_subset(backing, actual_reported_length,
subset_tvb_offset, subset_tvb_length);
tvb_add_to_chain(backing, tvb);
@@ -167,7 +173,8 @@ tvb_new_subset_length(tvbuff_t *backing, const gint backing_offset, const gint r
THROW_ON(reported_length < 0, ReportedBoundsError);
/*
- * Give the next dissector only captured_length bytes.
+ * Cut the captured length short, so it doesn't go past the subset's
+ * reported length.
*/
captured_length = tvb_captured_length_remaining(backing, backing_offset);
THROW_ON(captured_length < 0, BoundsError);
@@ -178,7 +185,7 @@ tvb_new_subset_length(tvbuff_t *backing, const gint backing_offset, const gint r
&subset_tvb_offset,
&subset_tvb_length);
- tvb = tvb_new_with_subset(backing, reported_length,
+ tvb = tvb_new_with_subset(backing, (guint)reported_length,
subset_tvb_offset, subset_tvb_length);
tvb_add_to_chain(backing, tvb);
@@ -192,12 +199,16 @@ tvb_new_subset_remaining(tvbuff_t *backing, const gint backing_offset)
tvbuff_t *tvb;
guint subset_tvb_offset;
guint subset_tvb_length;
+ guint reported_length;
tvb_check_offset_length(backing, backing_offset, -1 /* backing_length */,
&subset_tvb_offset,
&subset_tvb_length);
- tvb = tvb_new_with_subset(backing, -1 /* reported_length */,
+ THROW_ON(backing->reported_length < subset_tvb_offset, ReportedBoundsError);
+ reported_length = backing->reported_length - subset_tvb_offset;
+
+ tvb = tvb_new_with_subset(backing, reported_length,
subset_tvb_offset, subset_tvb_length);
tvb_add_to_chain(backing, tvb);