aboutsummaryrefslogtreecommitdiffstats
path: root/epan/tvbuff.c
diff options
context:
space:
mode:
authorAnders Broman <anders.broman@ericsson.com>2010-08-16 15:13:54 +0000
committerAnders Broman <anders.broman@ericsson.com>2010-08-16 15:13:54 +0000
commit63bffd3ac500750bbd60475c3e8836d800855c9d (patch)
tree5040c950a23a376e89c68980d617a22b95c73e46 /epan/tvbuff.c
parent3b07f8f423121c89df538e62308a6d258138ecb1 (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.c40
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;
}