aboutsummaryrefslogtreecommitdiffstats
path: root/epan/tvbuff.c
diff options
context:
space:
mode:
authorJohn Thacker <johnthacker@gmail.com>2022-09-02 08:34:35 -0400
committerA Wireshark GitLab Utility <gerald+gitlab-utility@wireshark.org>2022-09-03 20:05:41 +0000
commite76ebbdeccd1a9fc039fa450b34222dd42668c54 (patch)
tree642fd72cfce2d6bee02c9c640ed6678d9b133759 /epan/tvbuff.c
parent95b45b2555626729813578a1f5739820dc0acb33 (diff)
epan: Fix tvb_find_guint16 with previous partial matches
Fix tvb_find_guint16 when there is a partial match (first byte matches but second byte does not) in the buffer before an actual match. The function claims that it takes negative offsets and a negative maxlength value (for "to the end of the buffer.") Convert those to absolute offsets and limits at the start of the function rather than repeatedly having special checks for negatives. Fix the "number of bytes searched so far" calculation, which was only correct for negative offsets (but only used when there was a partial match.)
Diffstat (limited to 'epan/tvbuff.c')
-rw-r--r--epan/tvbuff.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/epan/tvbuff.c b/epan/tvbuff.c
index a93bc5258c..5d336a9e78 100644
--- a/epan/tvbuff.c
+++ b/epan/tvbuff.c
@@ -2291,23 +2291,38 @@ gint
tvb_find_guint16(tvbuff_t *tvb, const gint offset, const gint maxlength,
const guint16 needle)
{
+ guint abs_offset = 0;
+ guint limit = 0;
+ int exception;
+
+ exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &limit);
+ if (exception)
+ THROW(exception);
+
+ /* Only search to end of tvbuff, w/o throwing exception. */
+ if (maxlength >= 0 && limit > (guint) maxlength) {
+ /* Maximum length doesn't go past end of tvbuff; search
+ to that value. */
+ limit = (guint) maxlength;
+ }
+
const guint8 needle1 = ((needle & 0xFF00) >> 8);
const guint8 needle2 = ((needle & 0x00FF) >> 0);
- gint searched_bytes = 0;
- gint pos = offset;
+ guint searched_bytes = 0;
+ guint pos = abs_offset;
do {
gint offset1 =
- tvb_find_guint8(tvb, pos, maxlength - searched_bytes, needle1);
+ tvb_find_guint8(tvb, pos, limit - searched_bytes, needle1);
gint offset2 = -1;
if (offset1 == -1) {
return -1;
}
- searched_bytes = offset - pos + 1;
+ searched_bytes = (guint)offset1 - abs_offset + 1;
- if ((maxlength != -1) && (searched_bytes >= maxlength)) {
+ if (searched_bytes >= limit) {
return -1;
}
@@ -2316,14 +2331,14 @@ tvb_find_guint16(tvbuff_t *tvb, const gint offset, const gint maxlength,
searched_bytes += 1;
if (offset2 != -1) {
- if ((maxlength != -1) && (searched_bytes > maxlength)) {
+ if (searched_bytes > limit) {
return -1;
}
return offset1;
}
pos = offset1 + 1;
- } while (searched_bytes < maxlength);
+ } while (searched_bytes < limit);
return -1;
}