diff options
author | Anders Broman <anders.broman@ericsson.com> | 2010-08-16 15:13:54 +0000 |
---|---|---|
committer | Anders Broman <anders.broman@ericsson.com> | 2010-08-16 15:13:54 +0000 |
commit | 63bffd3ac500750bbd60475c3e8836d800855c9d (patch) | |
tree | 5040c950a23a376e89c68980d617a22b95c73e46 /epan/tvbuff.c | |
parent | 3b07f8f423121c89df538e62308a6d258138ecb1 (diff) |
From rodebiet:
tvb_get_bits32 produces malformed_packet if no_of_bits < 25 and tvb remaining = 3
https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5080
svn path=/trunk/; revision=33811
Diffstat (limited to 'epan/tvbuff.c')
-rw-r--r-- | epan/tvbuff.c | 40 |
1 files changed, 24 insertions, 16 deletions
diff --git a/epan/tvbuff.c b/epan/tvbuff.c index 2257ddc1af..ba842b3d71 100644 --- a/epan/tvbuff.c +++ b/epan/tvbuff.c @@ -1676,6 +1676,9 @@ tvb_get_bits32(tvbuff_t *tvb, gint bit_offset, const gint no_of_bits, const gboo guint32 value = 0; guint32 tempval = 0; guint8 tot_no_bits; + guint8 tot_no_octets = 0; + guint8 i = 0; + gint8 shift = 0; if ((no_of_bits<=16)||(no_of_bits>32)) { /* If bits <= 16 use tvb_get_bits8 or tvb_get_bits16 */ @@ -1689,24 +1692,29 @@ tvb_get_bits32(tvbuff_t *tvb, gint bit_offset, const gint no_of_bits, const gboo /* Byte align offset */ offset = bit_offset>>3; - /* Find out which mask to use for the most significant octet - * by convering bit_offset into the offset into the first - * fetched octet. - */ bit_offset = bit_offset & 0x7; tot_no_bits = bit_offset+no_of_bits; - /* Read four octets and mask off bit_offset bits */ - value = tvb_get_ntohl(tvb,offset) & bit_mask32[bit_offset]; - if(tot_no_bits < 32){ - /* Left shift out the unused bits */ - value = value >> (32 - tot_no_bits); - }else if(tot_no_bits > 32){ - /* Spans five octets, read next octet and shift as needed */ - value = value << (tot_no_bits - 32); - tempval = tvb_get_guint8(tvb,offset+4); - tempval = tempval >> (40-tot_no_bits); - value = value | tempval; - } + tot_no_octets = tot_no_bits / 8; + if (tot_no_bits % 8) tot_no_octets++; + shift = no_of_bits - (8 - bit_offset); + + value = tvb_get_guint8(tvb, offset) & bit_mask8[bit_offset]; + value = value << shift; + + for (i = 1; i < tot_no_octets; i++) + { + shift = shift - 8; + tempval = tvb_get_guint8(tvb, offset+i); + if (shift >= 0) + { + tempval = tempval << shift; + } + else + { + tempval = tempval >> (8 - shift); + } + value = value | tempval; + } return value; } |