diff options
author | John Thacker <johnthacker@gmail.com> | 2022-09-02 08:34:35 -0400 |
---|---|---|
committer | A Wireshark GitLab Utility <gerald+gitlab-utility@wireshark.org> | 2022-09-03 20:05:41 +0000 |
commit | e76ebbdeccd1a9fc039fa450b34222dd42668c54 (patch) | |
tree | 642fd72cfce2d6bee02c9c640ed6678d9b133759 /epan/tvbuff.c | |
parent | 95b45b2555626729813578a1f5739820dc0acb33 (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.c | 29 |
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; } |