|
|
dbc6ab |
diff --git a/epan/tvbuff.c b/epan/tvbuff.c
|
|
|
dbc6ab |
index 98968a0..db2cfd1 100644
|
|
|
dbc6ab |
--- a/epan/tvbuff.c
|
|
|
dbc6ab |
+++ b/epan/tvbuff.c
|
|
|
dbc6ab |
@@ -53,7 +53,7 @@
|
|
|
dbc6ab |
|
|
|
dbc6ab |
static const guint8*
|
|
|
dbc6ab |
ensure_contiguous_no_exception(tvbuff_t *tvb, const gint offset, const gint length,
|
|
|
dbc6ab |
- int *exception);
|
|
|
dbc6ab |
+ int *pexception);
|
|
|
dbc6ab |
|
|
|
dbc6ab |
static const guint8*
|
|
|
dbc6ab |
ensure_contiguous(tvbuff_t *tvb, const gint offset, const gint length);
|
|
|
dbc6ab |
@@ -241,45 +241,48 @@ tvb_new_child_real_data(tvbuff_t *parent, const guint8* data, const guint length
|
|
|
dbc6ab |
return tvb;
|
|
|
dbc6ab |
}
|
|
|
dbc6ab |
|
|
|
dbc6ab |
-/* Computes the absolute offset and length based on a possibly-negative offset
|
|
|
dbc6ab |
- * and a length that is possible -1 (which means "to the end of the data").
|
|
|
dbc6ab |
- * Returns TRUE/FALSE indicating whether the offset is in bounds or
|
|
|
dbc6ab |
- * not. The integer ptrs are modified with the new offset and length.
|
|
|
dbc6ab |
- * No exception is thrown.
|
|
|
dbc6ab |
+/*
|
|
|
dbc6ab |
+ * Check whether that offset goes more than one byte past the
|
|
|
dbc6ab |
+ * end of the buffer.
|
|
|
dbc6ab |
*
|
|
|
dbc6ab |
- * XXX - we return TRUE, not FALSE, if the offset is positive and right
|
|
|
dbc6ab |
- * after the end of the tvbuff (i.e., equal to the length). We do this
|
|
|
dbc6ab |
- * so that a dissector constructing a subset tvbuff for the next protocol
|
|
|
dbc6ab |
- * will get a zero-length tvbuff, not an exception, if there's no data
|
|
|
dbc6ab |
- * left for the next protocol - we want the next protocol to be the one
|
|
|
dbc6ab |
- * that gets an exception, so the error is reported as an error in that
|
|
|
dbc6ab |
- * protocol rather than the containing protocol. */
|
|
|
dbc6ab |
-static gboolean
|
|
|
dbc6ab |
-compute_offset_length(const tvbuff_t *tvb,
|
|
|
dbc6ab |
- const gint offset, const gint length_val,
|
|
|
dbc6ab |
- guint *offset_ptr, guint *length_ptr, int *exception)
|
|
|
dbc6ab |
+ * If not, return 0; otherwise, return exception
|
|
|
dbc6ab |
+ */
|
|
|
dbc6ab |
+static inline int
|
|
|
dbc6ab |
+validate_offset(const tvbuff_t *tvb, const guint abs_offset)
|
|
|
dbc6ab |
{
|
|
|
dbc6ab |
- DISSECTOR_ASSERT(offset_ptr);
|
|
|
dbc6ab |
- DISSECTOR_ASSERT(length_ptr);
|
|
|
dbc6ab |
+ int exception;
|
|
|
dbc6ab |
+
|
|
|
dbc6ab |
+ if (G_LIKELY(abs_offset <= tvb->length))
|
|
|
dbc6ab |
+ exception = 0;
|
|
|
dbc6ab |
+ else if (abs_offset <= tvb->reported_length)
|
|
|
dbc6ab |
+ exception = BoundsError;
|
|
|
dbc6ab |
+ else {
|
|
|
dbc6ab |
+ if (tvb->flags & TVBUFF_FRAGMENT)
|
|
|
dbc6ab |
+ exception = FragmentBoundsError;
|
|
|
dbc6ab |
+ else
|
|
|
dbc6ab |
+ exception = ReportedBoundsError;
|
|
|
dbc6ab |
+ }
|
|
|
dbc6ab |
+
|
|
|
dbc6ab |
+ return exception;
|
|
|
dbc6ab |
+}
|
|
|
dbc6ab |
+
|
|
|
dbc6ab |
+static int
|
|
|
dbc6ab |
+compute_offset(const tvbuff_t *tvb, const gint offset, guint *offset_ptr)
|
|
|
dbc6ab |
+{
|
|
|
dbc6ab |
+ int exception;
|
|
|
dbc6ab |
|
|
|
dbc6ab |
- /* Compute the offset */
|
|
|
dbc6ab |
if (offset >= 0) {
|
|
|
dbc6ab |
/* Positive offset - relative to the beginning of the packet. */
|
|
|
dbc6ab |
if ((guint) offset > tvb->reported_length) {
|
|
|
dbc6ab |
- if (exception) {
|
|
|
dbc6ab |
- if (tvb->flags & TVBUFF_FRAGMENT) {
|
|
|
dbc6ab |
- *exception = FragmentBoundsError;
|
|
|
dbc6ab |
- } else {
|
|
|
dbc6ab |
- *exception = ReportedBoundsError;
|
|
|
dbc6ab |
- }
|
|
|
dbc6ab |
+ if (tvb->flags & TVBUFF_FRAGMENT) {
|
|
|
dbc6ab |
+ exception = FragmentBoundsError;
|
|
|
dbc6ab |
+ } else {
|
|
|
dbc6ab |
+ exception = ReportedBoundsError;
|
|
|
dbc6ab |
}
|
|
|
dbc6ab |
- return FALSE;
|
|
|
dbc6ab |
+ return exception;
|
|
|
dbc6ab |
}
|
|
|
dbc6ab |
else if ((guint) offset > tvb->length) {
|
|
|
dbc6ab |
- if (exception) {
|
|
|
dbc6ab |
- *exception = BoundsError;
|
|
|
dbc6ab |
- }
|
|
|
dbc6ab |
- return FALSE;
|
|
|
dbc6ab |
+ return BoundsError;
|
|
|
dbc6ab |
}
|
|
|
dbc6ab |
else {
|
|
|
dbc6ab |
*offset_ptr = offset;
|
|
|
dbc6ab |
@@ -288,95 +291,90 @@ compute_offset_length(const tvbuff_t *tvb,
|
|
|
dbc6ab |
else {
|
|
|
dbc6ab |
/* Negative offset - relative to the end of the packet. */
|
|
|
dbc6ab |
if ((guint) -offset > tvb->reported_length) {
|
|
|
dbc6ab |
- if (exception) {
|
|
|
dbc6ab |
- if (tvb->flags & TVBUFF_FRAGMENT) {
|
|
|
dbc6ab |
- *exception = FragmentBoundsError;
|
|
|
dbc6ab |
- } else {
|
|
|
dbc6ab |
- *exception = ReportedBoundsError;
|
|
|
dbc6ab |
- }
|
|
|
dbc6ab |
+ if (tvb->flags & TVBUFF_FRAGMENT) {
|
|
|
dbc6ab |
+ exception = FragmentBoundsError;
|
|
|
dbc6ab |
+ } else {
|
|
|
dbc6ab |
+ exception = ReportedBoundsError;
|
|
|
dbc6ab |
}
|
|
|
dbc6ab |
- return FALSE;
|
|
|
dbc6ab |
+ return exception;
|
|
|
dbc6ab |
}
|
|
|
dbc6ab |
else if ((guint) -offset > tvb->length) {
|
|
|
dbc6ab |
- if (exception) {
|
|
|
dbc6ab |
- *exception = BoundsError;
|
|
|
dbc6ab |
- }
|
|
|
dbc6ab |
- return FALSE;
|
|
|
dbc6ab |
+ return BoundsError;
|
|
|
dbc6ab |
}
|
|
|
dbc6ab |
else {
|
|
|
dbc6ab |
*offset_ptr = tvb->length + offset;
|
|
|
dbc6ab |
}
|
|
|
dbc6ab |
}
|
|
|
dbc6ab |
|
|
|
dbc6ab |
- /* Compute the length */
|
|
|
dbc6ab |
- if (length_val < -1) {
|
|
|
dbc6ab |
- if (exception) {
|
|
|
dbc6ab |
- /* XXX - ReportedBoundsError? */
|
|
|
dbc6ab |
- *exception = BoundsError;
|
|
|
dbc6ab |
- }
|
|
|
dbc6ab |
- return FALSE;
|
|
|
dbc6ab |
- }
|
|
|
dbc6ab |
- else if (length_val == -1) {
|
|
|
dbc6ab |
- *length_ptr = tvb->length - *offset_ptr;
|
|
|
dbc6ab |
- }
|
|
|
dbc6ab |
- else {
|
|
|
dbc6ab |
- *length_ptr = length_val;
|
|
|
dbc6ab |
- }
|
|
|
dbc6ab |
+ return 0;
|
|
|
dbc6ab |
+}
|
|
|
dbc6ab |
|
|
|
dbc6ab |
- return TRUE;
|
|
|
dbc6ab |
+static int
|
|
|
dbc6ab |
+compute_offset_and_remaining(const tvbuff_t *tvb, const gint offset, guint *offset_ptr, guint *rem_len)
|
|
|
dbc6ab |
+{
|
|
|
dbc6ab |
+ int exception;
|
|
|
dbc6ab |
+
|
|
|
dbc6ab |
+ exception = compute_offset(tvb, offset, offset_ptr);
|
|
|
dbc6ab |
+ if (!exception)
|
|
|
dbc6ab |
+ *rem_len = tvb->length - *offset_ptr;
|
|
|
dbc6ab |
+
|
|
|
dbc6ab |
+ return exception;
|
|
|
dbc6ab |
}
|
|
|
dbc6ab |
|
|
|
dbc6ab |
-static gboolean
|
|
|
dbc6ab |
+/* Computes the absolute offset and length based on a possibly-negative offset
|
|
|
dbc6ab |
+ * and a length that is possible -1 (which means "to the end of the data").
|
|
|
dbc6ab |
+ * Returns integer indicating whether the offset is in bounds (0) or
|
|
|
dbc6ab |
+ * not (exception number). The integer ptrs are modified with the new offset and length.
|
|
|
dbc6ab |
+ * No exception is thrown.
|
|
|
dbc6ab |
+ *
|
|
|
dbc6ab |
+ * XXX - we return success (0), if the offset is positive and right
|
|
|
dbc6ab |
+ * after the end of the tvbuff (i.e., equal to the length). We do this
|
|
|
dbc6ab |
+ * so that a dissector constructing a subset tvbuff for the next protocol
|
|
|
dbc6ab |
+ * will get a zero-length tvbuff, not an exception, if there's no data
|
|
|
dbc6ab |
+ * left for the next protocol - we want the next protocol to be the one
|
|
|
dbc6ab |
+ * that gets an exception, so the error is reported as an error in that
|
|
|
dbc6ab |
+ * protocol rather than the containing protocol. */
|
|
|
dbc6ab |
+static int
|
|
|
dbc6ab |
check_offset_length_no_exception(const tvbuff_t *tvb,
|
|
|
dbc6ab |
const gint offset, gint const length_val,
|
|
|
dbc6ab |
- guint *offset_ptr, guint *length_ptr, int *exception)
|
|
|
dbc6ab |
+ guint *offset_ptr, guint *length_ptr)
|
|
|
dbc6ab |
{
|
|
|
dbc6ab |
- guint end_offset;
|
|
|
dbc6ab |
+ guint end_offset;
|
|
|
dbc6ab |
+ int exception;
|
|
|
dbc6ab |
|
|
|
dbc6ab |
- if (!compute_offset_length(tvb,
|
|
|
dbc6ab |
- offset, length_val, offset_ptr, length_ptr, exception)) {
|
|
|
dbc6ab |
- return FALSE;
|
|
|
dbc6ab |
+ DISSECTOR_ASSERT(offset_ptr);
|
|
|
dbc6ab |
+ DISSECTOR_ASSERT(length_ptr);
|
|
|
dbc6ab |
+
|
|
|
dbc6ab |
+ /* Compute the offset */
|
|
|
dbc6ab |
+ exception = compute_offset(tvb, offset, offset_ptr);
|
|
|
dbc6ab |
+ if (exception)
|
|
|
dbc6ab |
+ return exception;
|
|
|
dbc6ab |
+
|
|
|
dbc6ab |
+ if (length_val < -1) {
|
|
|
dbc6ab |
+ /* XXX - ReportedBoundsError? */
|
|
|
dbc6ab |
+ return BoundsError;
|
|
|
dbc6ab |
}
|
|
|
dbc6ab |
|
|
|
dbc6ab |
+ /* Compute the length */
|
|
|
dbc6ab |
+ if (length_val == -1)
|
|
|
dbc6ab |
+ *length_ptr = tvb->length - *offset_ptr;
|
|
|
dbc6ab |
+ else
|
|
|
dbc6ab |
+ *length_ptr = length_val;
|
|
|
dbc6ab |
+
|
|
|
dbc6ab |
/*
|
|
|
dbc6ab |
* Compute the offset of the first byte past the length.
|
|
|
dbc6ab |
*/
|
|
|
dbc6ab |
end_offset = *offset_ptr + *length_ptr;
|
|
|
dbc6ab |
|
|
|
dbc6ab |
/*
|
|
|
dbc6ab |
- * Check for an overflow, and clamp "end_offset" at the maximum
|
|
|
dbc6ab |
- * if we got an overflow - that should force us to indicate that
|
|
|
dbc6ab |
- * we're past the end of the tvbuff.
|
|
|
dbc6ab |
+ * Check for an overflow
|
|
|
dbc6ab |
*/
|
|
|
dbc6ab |
if (end_offset < *offset_ptr)
|
|
|
dbc6ab |
- end_offset = UINT_MAX;
|
|
|
dbc6ab |
-
|
|
|
dbc6ab |
- /*
|
|
|
dbc6ab |
- * Check whether that offset goes more than one byte past the
|
|
|
dbc6ab |
- * end of the buffer.
|
|
|
dbc6ab |
- *
|
|
|
dbc6ab |
- * If not, return TRUE; otherwise, return FALSE and, if "exception"
|
|
|
dbc6ab |
- * is non-null, return the appropriate exception through it.
|
|
|
dbc6ab |
- */
|
|
|
dbc6ab |
- if (end_offset <= tvb->length) {
|
|
|
dbc6ab |
- return TRUE;
|
|
|
dbc6ab |
- }
|
|
|
dbc6ab |
- else {
|
|
|
dbc6ab |
- if (exception) {
|
|
|
dbc6ab |
- if (end_offset <= tvb->reported_length) {
|
|
|
dbc6ab |
- *exception = BoundsError;
|
|
|
dbc6ab |
- }
|
|
|
dbc6ab |
- else {
|
|
|
dbc6ab |
- if (tvb->flags & TVBUFF_FRAGMENT) {
|
|
|
dbc6ab |
- *exception = FragmentBoundsError;
|
|
|
dbc6ab |
- } else {
|
|
|
dbc6ab |
- *exception = ReportedBoundsError;
|
|
|
dbc6ab |
- }
|
|
|
dbc6ab |
- }
|
|
|
dbc6ab |
- }
|
|
|
dbc6ab |
+ exception = BoundsError;
|
|
|
dbc6ab |
+ else
|
|
|
dbc6ab |
+ exception = validate_offset(tvb, end_offset);
|
|
|
dbc6ab |
|
|
|
dbc6ab |
- return FALSE;
|
|
|
dbc6ab |
- }
|
|
|
dbc6ab |
+ return exception;
|
|
|
dbc6ab |
}
|
|
|
dbc6ab |
|
|
|
dbc6ab |
/* Checks (+/-) offset and length and throws an exception if
|
|
|
dbc6ab |
@@ -387,13 +385,11 @@ check_offset_length(const tvbuff_t *tvb,
|
|
|
dbc6ab |
const gint offset, gint const length_val,
|
|
|
dbc6ab |
guint *offset_ptr, guint *length_ptr)
|
|
|
dbc6ab |
{
|
|
|
dbc6ab |
- int exception = 0;
|
|
|
dbc6ab |
-
|
|
|
dbc6ab |
- if (!check_offset_length_no_exception(tvb,
|
|
|
dbc6ab |
- offset, length_val, offset_ptr, length_ptr, &exception)) {
|
|
|
dbc6ab |
- DISSECTOR_ASSERT(exception > 0);
|
|
|
dbc6ab |
+ int exception;
|
|
|
dbc6ab |
+
|
|
|
dbc6ab |
+ exception = check_offset_length_no_exception(tvb, offset, length_val, offset_ptr, length_ptr);
|
|
|
dbc6ab |
+ if (exception)
|
|
|
dbc6ab |
THROW(exception);
|
|
|
dbc6ab |
- }
|
|
|
dbc6ab |
}
|
|
|
dbc6ab |
|
|
|
dbc6ab |
static tvbuff_t *
|
|
|
dbc6ab |
@@ -538,7 +534,7 @@ tvb_new_octet_aligned(tvbuff_t *tvb, guint32 bit_offset, gint32 no_of_bits)
|
|
|
dbc6ab |
right = 8 - left; /* for right-shifting */
|
|
|
dbc6ab |
|
|
|
dbc6ab |
if (no_of_bits == -1) {
|
|
|
dbc6ab |
- datalen = tvb_length_remaining(tvb, byte_offset);
|
|
|
dbc6ab |
+ datalen = tvb_captured_length_remaining(tvb, byte_offset);
|
|
|
dbc6ab |
remaining_bits = 0;
|
|
|
dbc6ab |
} else {
|
|
|
dbc6ab |
datalen = no_of_bits >> 3;
|
|
|
dbc6ab |
@@ -560,7 +556,7 @@ tvb_new_octet_aligned(tvbuff_t *tvb, guint32 bit_offset, gint32 no_of_bits)
|
|
|
dbc6ab |
* if non extra byte is available, the last shifted byte requires
|
|
|
dbc6ab |
* special treatment
|
|
|
dbc6ab |
*/
|
|
|
dbc6ab |
- if (tvb_length_remaining(tvb, byte_offset) > datalen) {
|
|
|
dbc6ab |
+ if (tvb_captured_length_remaining(tvb, byte_offset) > datalen) {
|
|
|
dbc6ab |
data = tvb_get_ptr(tvb, byte_offset, datalen + 1);
|
|
|
dbc6ab |
|
|
|
dbc6ab |
/* Do this allocation AFTER tvb_get_ptr() (which could throw an exception) */
|
|
|
dbc6ab |
@@ -679,7 +675,7 @@ tvb_composite_finalize(tvbuff_t *tvb)
|
|
|
dbc6ab |
|
|
|
dbc6ab |
|
|
|
dbc6ab |
guint
|
|
|
dbc6ab |
-tvb_length(const tvbuff_t *tvb)
|
|
|
dbc6ab |
+tvb_captured_length(const tvbuff_t *tvb)
|
|
|
dbc6ab |
{
|
|
|
dbc6ab |
DISSECTOR_ASSERT(tvb && tvb->initialized);
|
|
|
dbc6ab |
|
|
|
dbc6ab |
@@ -687,32 +683,33 @@ tvb_length(const tvbuff_t *tvb)
|
|
|
dbc6ab |
}
|
|
|
dbc6ab |
|
|
|
dbc6ab |
gint
|
|
|
dbc6ab |
-tvb_length_remaining(const tvbuff_t *tvb, const gint offset)
|
|
|
dbc6ab |
+tvb_captured_length_remaining(const tvbuff_t *tvb, const gint offset)
|
|
|
dbc6ab |
{
|
|
|
dbc6ab |
- guint abs_offset, abs_length;
|
|
|
dbc6ab |
+ guint abs_offset, rem_length;
|
|
|
dbc6ab |
+ int exception;
|
|
|
dbc6ab |
|
|
|
dbc6ab |
DISSECTOR_ASSERT(tvb && tvb->initialized);
|
|
|
dbc6ab |
|
|
|
dbc6ab |
- if (compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, NULL)) {
|
|
|
dbc6ab |
- return abs_length;
|
|
|
dbc6ab |
- }
|
|
|
dbc6ab |
- else {
|
|
|
dbc6ab |
- return -1;
|
|
|
dbc6ab |
- }
|
|
|
dbc6ab |
+ exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &rem_length);
|
|
|
dbc6ab |
+ if (exception)
|
|
|
dbc6ab |
+ return 0;
|
|
|
dbc6ab |
+
|
|
|
dbc6ab |
+ return rem_length;
|
|
|
dbc6ab |
}
|
|
|
dbc6ab |
|
|
|
dbc6ab |
guint
|
|
|
dbc6ab |
-tvb_ensure_length_remaining(const tvbuff_t *tvb, const gint offset)
|
|
|
dbc6ab |
+tvb_ensure_captured_length_remaining(const tvbuff_t *tvb, const gint offset)
|
|
|
dbc6ab |
{
|
|
|
dbc6ab |
- guint abs_offset, abs_length;
|
|
|
dbc6ab |
+ guint abs_offset, rem_length;
|
|
|
dbc6ab |
int exception;
|
|
|
dbc6ab |
|
|
|
dbc6ab |
DISSECTOR_ASSERT(tvb && tvb->initialized);
|
|
|
dbc6ab |
|
|
|
dbc6ab |
- if (!compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, &exception)) {
|
|
|
dbc6ab |
+ exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &rem_length);
|
|
|
dbc6ab |
+ if (exception)
|
|
|
dbc6ab |
THROW(exception);
|
|
|
dbc6ab |
- }
|
|
|
dbc6ab |
- if (abs_length == 0) {
|
|
|
dbc6ab |
+
|
|
|
dbc6ab |
+ if (rem_length == 0) {
|
|
|
dbc6ab |
/*
|
|
|
dbc6ab |
* This routine ensures there's at least one byte available.
|
|
|
dbc6ab |
* There aren't any bytes available, so throw the appropriate
|
|
|
dbc6ab |
@@ -727,7 +724,7 @@ tvb_ensure_length_remaining(const tvbuff_t *tvb, const gint offset)
|
|
|
dbc6ab |
} else
|
|
|
dbc6ab |
THROW(BoundsError);
|
|
|
dbc6ab |
}
|
|
|
dbc6ab |
- return abs_length;
|
|
|
dbc6ab |
+ return rem_length;
|
|
|
dbc6ab |
}
|
|
|
dbc6ab |
|
|
|
dbc6ab |
|
|
|
dbc6ab |
@@ -739,18 +736,15 @@ gboolean
|
|
|
dbc6ab |
tvb_bytes_exist(const tvbuff_t *tvb, const gint offset, const gint length)
|
|
|
dbc6ab |
{
|
|
|
dbc6ab |
guint abs_offset, abs_length;
|
|
|
dbc6ab |
+ int exception;
|
|
|
dbc6ab |
|
|
|
dbc6ab |
DISSECTOR_ASSERT(tvb && tvb->initialized);
|
|
|
dbc6ab |
|
|
|
dbc6ab |
- if (!compute_offset_length(tvb, offset, length, &abs_offset, &abs_length, NULL))
|
|
|
dbc6ab |
+ exception = check_offset_length_no_exception(tvb, offset, length, &abs_offset, &abs_length);
|
|
|
dbc6ab |
+ if (exception)
|
|
|
dbc6ab |
return FALSE;
|
|
|
dbc6ab |
|
|
|
dbc6ab |
- if (abs_offset + abs_length <= tvb->length) {
|
|
|
dbc6ab |
- return TRUE;
|
|
|
dbc6ab |
- }
|
|
|
dbc6ab |
- else {
|
|
|
dbc6ab |
- return FALSE;
|
|
|
dbc6ab |
- }
|
|
|
dbc6ab |
+ return TRUE;
|
|
|
dbc6ab |
}
|
|
|
dbc6ab |
|
|
|
dbc6ab |
/* Validates that 'length' bytes are available starting from
|
|
|
dbc6ab |
@@ -781,10 +775,13 @@ tvb_ensure_bytes_exist(const tvbuff_t *tvb, const gint offset, const gint length
|
|
|
dbc6ab |
gboolean
|
|
|
dbc6ab |
tvb_offset_exists(const tvbuff_t *tvb, const gint offset)
|
|
|
dbc6ab |
{
|
|
|
dbc6ab |
- guint abs_offset, abs_length;
|
|
|
dbc6ab |
+ guint abs_offset;
|
|
|
dbc6ab |
+ int exception;
|
|
|
dbc6ab |
|
|
|
dbc6ab |
DISSECTOR_ASSERT(tvb && tvb->initialized);
|
|
|
dbc6ab |
- if (!compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, NULL))
|
|
|
dbc6ab |
+
|
|
|
dbc6ab |
+ exception = compute_offset(tvb, offset, &abs_offset);
|
|
|
dbc6ab |
+ if (exception)
|
|
|
dbc6ab |
return FALSE;
|
|
|
dbc6ab |
|
|
|
dbc6ab |
if (abs_offset < tvb->length) {
|
|
|
dbc6ab |
@@ -806,19 +803,19 @@ tvb_reported_length(const tvbuff_t *tvb)
|
|
|
dbc6ab |
gint
|
|
|
dbc6ab |
tvb_reported_length_remaining(const tvbuff_t *tvb, const gint offset)
|
|
|
dbc6ab |
{
|
|
|
dbc6ab |
- guint abs_offset, abs_length;
|
|
|
dbc6ab |
+ guint abs_offset;
|
|
|
dbc6ab |
+ int exception;
|
|
|
dbc6ab |
|
|
|
dbc6ab |
DISSECTOR_ASSERT(tvb && tvb->initialized);
|
|
|
dbc6ab |
|
|
|
dbc6ab |
- if (compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, NULL)) {
|
|
|
dbc6ab |
- if (tvb->reported_length >= abs_offset)
|
|
|
dbc6ab |
- return tvb->reported_length - abs_offset;
|
|
|
dbc6ab |
- else
|
|
|
dbc6ab |
- return -1;
|
|
|
dbc6ab |
- }
|
|
|
dbc6ab |
- else {
|
|
|
dbc6ab |
- return -1;
|
|
|
dbc6ab |
- }
|
|
|
dbc6ab |
+ exception = compute_offset(tvb, offset, &abs_offset);
|
|
|
dbc6ab |
+ if (exception)
|
|
|
dbc6ab |
+ return 0;
|
|
|
dbc6ab |
+
|
|
|
dbc6ab |
+ if (tvb->reported_length >= abs_offset)
|
|
|
dbc6ab |
+ return tvb->reported_length - abs_offset;
|
|
|
dbc6ab |
+ else
|
|
|
dbc6ab |
+ return 0;
|
|
|
dbc6ab |
}
|
|
|
dbc6ab |
|
|
|
dbc6ab |
/* Set the reported length of a tvbuff to a given value; used for protocols
|
|
|
dbc6ab |
@@ -896,6 +893,7 @@ composite_ensure_contiguous_no_exception(tvbuff_t *tvb, const guint abs_offset,
|
|
|
dbc6ab |
tvbuff_t *member_tvb = NULL;
|
|
|
dbc6ab |
guint member_offset, member_length;
|
|
|
dbc6ab |
GSList *slist;
|
|
|
dbc6ab |
+ int exception;
|
|
|
dbc6ab |
|
|
|
dbc6ab |
DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
|
|
|
dbc6ab |
|
|
|
dbc6ab |
@@ -913,10 +911,11 @@ composite_ensure_contiguous_no_exception(tvbuff_t *tvb, const guint abs_offset,
|
|
|
dbc6ab |
}
|
|
|
dbc6ab |
DISSECTOR_ASSERT(member_tvb);
|
|
|
dbc6ab |
|
|
|
dbc6ab |
- if (check_offset_length_no_exception(member_tvb,
|
|
|
dbc6ab |
+ exception = check_offset_length_no_exception(member_tvb,
|
|
|
dbc6ab |
abs_offset - composite->start_offsets[i],
|
|
|
dbc6ab |
- abs_length, &member_offset, &member_length, NULL)) {
|
|
|
dbc6ab |
+ abs_length, &member_offset, &member_length);
|
|
|
dbc6ab |
|
|
|
dbc6ab |
+ if (!exception) {
|
|
|
dbc6ab |
/*
|
|
|
dbc6ab |
* The range is, in fact, contiguous within member_tvb.
|
|
|
dbc6ab |
*/
|
|
|
dbc6ab |
@@ -932,12 +931,15 @@ composite_ensure_contiguous_no_exception(tvbuff_t *tvb, const guint abs_offset,
|
|
|
dbc6ab |
}
|
|
|
dbc6ab |
|
|
|
dbc6ab |
static const guint8*
|
|
|
dbc6ab |
-ensure_contiguous_no_exception(tvbuff_t *tvb, const gint offset, const gint length, int *exception)
|
|
|
dbc6ab |
+ensure_contiguous_no_exception(tvbuff_t *tvb, const gint offset, const gint length, int *pexception)
|
|
|
dbc6ab |
{
|
|
|
dbc6ab |
guint abs_offset, abs_length;
|
|
|
dbc6ab |
+ int exception;
|
|
|
dbc6ab |
|
|
|
dbc6ab |
- if (!check_offset_length_no_exception(tvb, offset, length,
|
|
|
dbc6ab |
- &abs_offset, &abs_length, exception)) {
|
|
|
dbc6ab |
+ exception = check_offset_length_no_exception(tvb, offset, length, &abs_offset, &abs_length);
|
|
|
dbc6ab |
+ if (exception) {
|
|
|
dbc6ab |
+ if (pexception)
|
|
|
dbc6ab |
+ *pexception = exception;
|
|
|
dbc6ab |
return NULL;
|
|
|
dbc6ab |
}
|
|
|
dbc6ab |
|
|
|
dbc6ab |
@@ -1046,7 +1048,7 @@ composite_memcpy(tvbuff_t *tvb, guint8* target, guint abs_offset, size_t abs_len
|
|
|
dbc6ab |
tvb_comp_t *composite;
|
|
|
dbc6ab |
tvbuff_t *member_tvb = NULL;
|
|
|
dbc6ab |
guint member_offset, member_length;
|
|
|
dbc6ab |
- gboolean retval;
|
|
|
dbc6ab |
+ int exception;
|
|
|
dbc6ab |
GSList *slist;
|
|
|
dbc6ab |
|
|
|
dbc6ab |
DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
|
|
|
dbc6ab |
@@ -1065,9 +1067,10 @@ composite_memcpy(tvbuff_t *tvb, guint8* target, guint abs_offset, size_t abs_len
|
|
|
dbc6ab |
}
|
|
|
dbc6ab |
DISSECTOR_ASSERT(member_tvb);
|
|
|
dbc6ab |
|
|
|
dbc6ab |
- if (check_offset_length_no_exception(member_tvb, abs_offset - composite->start_offsets[i],
|
|
|
dbc6ab |
- (gint) abs_length, &member_offset, &member_length, NULL)) {
|
|
|
dbc6ab |
-
|
|
|
dbc6ab |
+ exception = check_offset_length_no_exception(member_tvb, abs_offset - composite->start_offsets[i],
|
|
|
dbc6ab |
+ (gint) abs_length, &member_offset, &member_length);
|
|
|
dbc6ab |
+
|
|
|
dbc6ab |
+ if (!exception) {
|
|
|
dbc6ab |
DISSECTOR_ASSERT(!tvb->real_data);
|
|
|
dbc6ab |
return tvb_memcpy(member_tvb, target, member_offset, member_length);
|
|
|
dbc6ab |
}
|
|
|
dbc6ab |
@@ -1077,9 +1080,9 @@ composite_memcpy(tvbuff_t *tvb, guint8* target, guint abs_offset, size_t abs_len
|
|
|
dbc6ab |
* then iterate across the other member tvb's, copying their portions
|
|
|
dbc6ab |
* until we have copied all data.
|
|
|
dbc6ab |
*/
|
|
|
dbc6ab |
- retval = compute_offset_length(member_tvb, abs_offset - composite->start_offsets[i], -1,
|
|
|
dbc6ab |
- &member_offset, &member_length, NULL);
|
|
|
dbc6ab |
- DISSECTOR_ASSERT(retval);
|
|
|
dbc6ab |
+ exception = compute_offset_and_remaining(member_tvb, abs_offset - composite->start_offsets[i],
|
|
|
dbc6ab |
+ &member_offset, &member_length);
|
|
|
dbc6ab |
+ DISSECTOR_ASSERT(!exception);
|
|
|
dbc6ab |
|
|
|
dbc6ab |
/* composite_memcpy() can't handle a member_length of zero. */
|
|
|
dbc6ab |
DISSECTOR_ASSERT(member_length);
|
|
|
dbc6ab |
@@ -1909,6 +1912,21 @@ tvb_get_bits(tvbuff_t *tvb, const guint bit_offset, const gint no_of_bits, const
|
|
|
dbc6ab |
return (guint32)_tvb_get_bits64(tvb, bit_offset, no_of_bits);
|
|
|
dbc6ab |
}
|
|
|
dbc6ab |
|
|
|
dbc6ab |
+static gint
|
|
|
dbc6ab |
+tvb_find_guint8_generic(tvbuff_t *tvb, guint abs_offset, guint limit, guint8 needle)
|
|
|
dbc6ab |
+{
|
|
|
dbc6ab |
+ const guint8 *ptr;
|
|
|
dbc6ab |
+ const guint8 *result;
|
|
|
dbc6ab |
+
|
|
|
dbc6ab |
+ ptr = tvb_get_ptr(tvb, abs_offset, limit);
|
|
|
dbc6ab |
+
|
|
|
dbc6ab |
+ result = (const guint8 *) memchr(ptr, needle, limit);
|
|
|
dbc6ab |
+ if (!result)
|
|
|
dbc6ab |
+ return -1;
|
|
|
dbc6ab |
+
|
|
|
dbc6ab |
+ return (gint) ((result - ptr) + abs_offset);
|
|
|
dbc6ab |
+}
|
|
|
dbc6ab |
+
|
|
|
dbc6ab |
/* Find first occurrence of needle in tvbuff, starting at offset. Searches
|
|
|
dbc6ab |
* at most maxlength number of bytes; if maxlength is -1, searches to
|
|
|
dbc6ab |
* end of tvbuff.
|
|
|
dbc6ab |
@@ -1920,16 +1938,15 @@ gint
|
|
|
dbc6ab |
tvb_find_guint8(tvbuff_t *tvb, const gint offset, const gint maxlength, const guint8 needle)
|
|
|
dbc6ab |
{
|
|
|
dbc6ab |
const guint8 *result;
|
|
|
dbc6ab |
- guint abs_offset, junk_length;
|
|
|
dbc6ab |
+ guint abs_offset;
|
|
|
dbc6ab |
guint tvbufflen;
|
|
|
dbc6ab |
guint limit;
|
|
|
dbc6ab |
|
|
|
dbc6ab |
DISSECTOR_ASSERT(tvb && tvb->initialized);
|
|
|
dbc6ab |
|
|
|
dbc6ab |
- check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
|
|
|
dbc6ab |
+ check_offset_length(tvb, offset, -1, &abs_offset, &tvbufflen);
|
|
|
dbc6ab |
|
|
|
dbc6ab |
/* Only search to end of tvbuff, w/o throwing exception. */
|
|
|
dbc6ab |
- tvbufflen = tvb_length_remaining(tvb, abs_offset);
|
|
|
dbc6ab |
if (maxlength == -1) {
|
|
|
dbc6ab |
/* No maximum length specified; search to end of tvbuff. */
|
|
|
dbc6ab |
limit = tvbufflen;
|
|
|
dbc6ab |
@@ -1985,16 +2002,15 @@ gint
|
|
|
dbc6ab |
tvb_pbrk_guint8(tvbuff_t *tvb, const gint offset, const gint maxlength, const guint8 *needles, guchar *found_needle)
|
|
|
dbc6ab |
{
|
|
|
dbc6ab |
const guint8 *result;
|
|
|
dbc6ab |
- guint abs_offset, junk_length;
|
|
|
dbc6ab |
+ guint abs_offset;
|
|
|
dbc6ab |
guint tvbufflen;
|
|
|
dbc6ab |
guint limit;
|
|
|
dbc6ab |
|
|
|
dbc6ab |
DISSECTOR_ASSERT(tvb && tvb->initialized);
|
|
|
dbc6ab |
|
|
|
dbc6ab |
- check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
|
|
|
dbc6ab |
+ check_offset_length(tvb, offset, -1, &abs_offset, &tvbufflen);
|
|
|
dbc6ab |
|
|
|
dbc6ab |
/* Only search to end of tvbuff, w/o throwing exception. */
|
|
|
dbc6ab |
- tvbufflen = tvb_length_remaining(tvb, abs_offset);
|
|
|
dbc6ab |
if (maxlength == -1) {
|
|
|
dbc6ab |
/* No maximum length specified; search to end of tvbuff. */
|
|
|
dbc6ab |
limit = tvbufflen;
|
|
|
dbc6ab |
@@ -2845,11 +2861,12 @@ static gint
|
|
|
dbc6ab |
_tvb_get_nstringz(tvbuff_t *tvb, const gint offset, const guint bufsize, guint8* buffer, gint *bytes_copied)
|
|
|
dbc6ab |
{
|
|
|
dbc6ab |
gint stringlen;
|
|
|
dbc6ab |
- guint abs_offset, junk_length;
|
|
|
dbc6ab |
+ guint abs_offset;
|
|
|
dbc6ab |
gint limit, len;
|
|
|
dbc6ab |
gboolean decreased_max = FALSE;
|
|
|
dbc6ab |
|
|
|
dbc6ab |
- check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
|
|
|
dbc6ab |
+ /* Only read to end of tvbuff, w/o throwing exception. */
|
|
|
dbc6ab |
+ check_offset_length(tvb, offset, -1, &abs_offset, &len;;
|
|
|
dbc6ab |
|
|
|
dbc6ab |
/* There must at least be room for the terminating NUL. */
|
|
|
dbc6ab |
DISSECTOR_ASSERT(bufsize != 0);
|
|
|
dbc6ab |
@@ -2861,9 +2878,6 @@ _tvb_get_nstringz(tvbuff_t *tvb, const gint offset, const guint bufsize, guint8*
|
|
|
dbc6ab |
return 0;
|
|
|
dbc6ab |
}
|
|
|
dbc6ab |
|
|
|
dbc6ab |
- /* Only read to end of tvbuff, w/o throwing exception. */
|
|
|
dbc6ab |
- len = tvb_length_remaining(tvb, abs_offset);
|
|
|
dbc6ab |
-
|
|
|
dbc6ab |
/* check_offset_length() won't throw an exception if we're
|
|
|
dbc6ab |
* looking at the byte immediately after the end of the tvbuff. */
|
|
|
dbc6ab |
if (len == 0) {
|
|
|
dbc6ab |
@@ -2984,7 +2998,7 @@ tvb_find_line_end(tvbuff_t *tvb, const gint offset, int len, gint *next_offset,
|
|
|
dbc6ab |
guchar found_needle = 0;
|
|
|
dbc6ab |
|
|
|
dbc6ab |
if (len == -1)
|
|
|
dbc6ab |
- len = tvb_length_remaining(tvb, offset);
|
|
|
dbc6ab |
+ len = tvb_captured_length_remaining(tvb, offset);
|
|
|
dbc6ab |
/*
|
|
|
dbc6ab |
* XXX - what if "len" is still -1, meaning "offset is past the
|
|
|
dbc6ab |
* end of the tvbuff"?
|
|
|
dbc6ab |
@@ -3100,7 +3114,7 @@ tvb_find_line_end_unquoted(tvbuff_t *tvb, const gint offset, int len, gint *next
|
|
|
dbc6ab |
int linelen;
|
|
|
dbc6ab |
|
|
|
dbc6ab |
if (len == -1)
|
|
|
dbc6ab |
- len = tvb_length_remaining(tvb, offset);
|
|
|
dbc6ab |
+ len = tvb_captured_length_remaining(tvb, offset);
|
|
|
dbc6ab |
/*
|
|
|
dbc6ab |
* XXX - what if "len" is still -1, meaning "offset is past the
|
|
|
dbc6ab |
* end of the tvbuff"?
|
|
|
dbc6ab |
@@ -3238,7 +3252,7 @@ tvb_skip_wsp(tvbuff_t *tvb, const gint offset, const gint maxlength)
|
|
|
dbc6ab |
guint8 tempchar;
|
|
|
dbc6ab |
|
|
|
dbc6ab |
/* Get the length remaining */
|
|
|
dbc6ab |
- tvb_len = tvb_length(tvb);
|
|
|
dbc6ab |
+ tvb_len = tvb_captured_length(tvb);
|
|
|
dbc6ab |
end = offset + maxlength;
|
|
|
dbc6ab |
if (end >= tvb_len)
|
|
|
dbc6ab |
{
|
|
|
dbc6ab |
@@ -3310,7 +3324,7 @@ tvb_bcd_dig_to_ep_str(tvbuff_t *tvb, const gint offset, const gint len, dgt_set_
|
|
|
dbc6ab |
dgt = &Dgt1_9_bcd;
|
|
|
dbc6ab |
|
|
|
dbc6ab |
if (len == -1) {
|
|
|
dbc6ab |
- length = tvb_length(tvb);
|
|
|
dbc6ab |
+ length = tvb_captured_length(tvb);
|
|
|
dbc6ab |
if (length < offset) {
|
|
|
dbc6ab |
return "";
|
|
|
dbc6ab |
}
|
|
|
dbc6ab |
diff --git a/epan/tvbuff.h b/epan/tvbuff.h
|
|
|
dbc6ab |
index 8950feb..f815c1f 100644
|
|
|
dbc6ab |
--- a/epan/tvbuff.h
|
|
|
dbc6ab |
+++ b/epan/tvbuff.h
|
|
|
dbc6ab |
@@ -213,16 +213,28 @@ WS_DLL_PUBLIC tvbuff_t* tvb_new_composite(void);
|
|
|
dbc6ab |
WS_DLL_PUBLIC void tvb_composite_finalize(tvbuff_t* tvb);
|
|
|
dbc6ab |
|
|
|
dbc6ab |
|
|
|
dbc6ab |
-/* Get total length of buffer */
|
|
|
dbc6ab |
-WS_DLL_PUBLIC guint tvb_length(const tvbuff_t*);
|
|
|
dbc6ab |
+/* Get amount of captured data in the buffer (which is *NOT* necessarily the
|
|
|
dbc6ab |
+ * * length of the packet). You probably want tvb_reported_length instead. */
|
|
|
dbc6ab |
+WS_DLL_PUBLIC guint tvb_captured_length(const tvbuff_t *tvb);
|
|
|
dbc6ab |
+
|
|
|
dbc6ab |
+/* DEPRECATED, do not use in new code, call tvb_captured_length directly! */
|
|
|
dbc6ab |
+#define tvb_length tvb_captured_length
|
|
|
dbc6ab |
|
|
|
dbc6ab |
/** Computes bytes to end of buffer, from offset (which can be negative,
|
|
|
dbc6ab |
- * to indicate bytes from end of buffer). Function returns -1 to
|
|
|
dbc6ab |
- * indicate that offset is out of bounds. No exception is thrown. */
|
|
|
dbc6ab |
-WS_DLL_PUBLIC gint tvb_length_remaining(const tvbuff_t*, const gint offset);
|
|
|
dbc6ab |
+ * to indicate bytes from end of buffer). Function returns 0 if offset is out
|
|
|
dbc6ab |
+ * of bounds. No exception is thrown. */
|
|
|
dbc6ab |
+WS_DLL_PUBLIC gint tvb_captured_length_remaining(const tvbuff_t *tvb, const gint offset);
|
|
|
dbc6ab |
+
|
|
|
dbc6ab |
+/* DEPRECATED, do not use in new code, call tvb_captured_length_remaining directly! */
|
|
|
dbc6ab |
+#define tvb_length_remaining tvb_captured_length_remaining
|
|
|
dbc6ab |
+
|
|
|
dbc6ab |
|
|
|
dbc6ab |
/** Same as above, but throws an exception if the offset is out of bounds. */
|
|
|
dbc6ab |
-WS_DLL_PUBLIC guint tvb_ensure_length_remaining(const tvbuff_t*, const gint offset);
|
|
|
dbc6ab |
+WS_DLL_PUBLIC guint tvb_ensure_captured_length_remaining(const tvbuff_t *tvb,
|
|
|
dbc6ab |
+ const gint offset);
|
|
|
dbc6ab |
+
|
|
|
dbc6ab |
+/* DEPRECATED, do not use in new code, call tvb_ensure_captured_length_remaining directly! */
|
|
|
dbc6ab |
+#define tvb_ensure_length_remaining tvb_ensure_captured_length_remaining
|
|
|
dbc6ab |
|
|
|
dbc6ab |
/* Checks (w/o throwing exception) that the bytes referred to by
|
|
|
dbc6ab |
* 'offset'/'length' actually exist in the buffer */
|
|
|
dbc6ab |
@@ -240,8 +252,7 @@ WS_DLL_PUBLIC guint tvb_reported_length(const tvbuff_t*);
|
|
|
dbc6ab |
|
|
|
dbc6ab |
/** Computes bytes of reported packet data to end of buffer, from offset
|
|
|
dbc6ab |
* (which can be negative, to indicate bytes from end of buffer). Function
|
|
|
dbc6ab |
- * returns -1 to indicate that offset is out of bounds. No exception is
|
|
|
dbc6ab |
- * thrown. */
|
|
|
dbc6ab |
+ * returns 0 if offset is out of bounds. No exception is thrown. */
|
|
|
dbc6ab |
WS_DLL_PUBLIC gint tvb_reported_length_remaining(const tvbuff_t *tvb, const gint offset);
|
|
|
dbc6ab |
|
|
|
dbc6ab |
/** Set the reported length of a tvbuff to a given value; used for protocols
|