From 75b86a9cd453c39889b27b3701135f64062f41f9 Mon Sep 17 00:00:00 2001 From: Anders Broman Date: Mon, 26 Sep 2011 17:19:54 +0000 Subject: From Pascal Quantin: When building the last byte, the remaining number of bits isn't masked. svn path=/trunk/; revision=39152 --- epan/tvbuff.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) (limited to 'epan/tvbuff.c') diff --git a/epan/tvbuff.c b/epan/tvbuff.c index 6e36c23397..2a5bed0215 100644 --- a/epan/tvbuff.c +++ b/epan/tvbuff.c @@ -115,13 +115,24 @@ tvb_new(const tvbuff_type type) return tvb; } +static const unsigned char left_aligned_bitmask[] = { + 0xff, + 0x80, + 0xc0, + 0xe0, + 0xf0, + 0xf8, + 0xfc, + 0xfe +}; + tvbuff_t * tvb_new_octet_aligned(tvbuff_t *tvb, guint32 bit_offset, gint32 no_of_bits) { tvbuff_t *sub_tvb = NULL; guint32 byte_offset; gint32 datalen, i; - guint8 left, right, *buf; + guint8 left, right, remaining_bits, *buf; const guint8 *data; byte_offset = bit_offset >> 3; @@ -130,9 +141,13 @@ tvb_new_octet_aligned(tvbuff_t *tvb, guint32 bit_offset, gint32 no_of_bits) if (no_of_bits == -1) { datalen = tvb_length_remaining(tvb, byte_offset); + remaining_bits = 0; } else { datalen = no_of_bits >> 3; - if (no_of_bits % 8) datalen++; + remaining_bits = no_of_bits % 8; + if (remaining_bits){ + datalen++; + } } /* already aligned -> shortcut */ @@ -149,14 +164,17 @@ tvb_new_octet_aligned(tvbuff_t *tvb, guint32 bit_offset, gint32 no_of_bits) */ if (tvb_length_remaining(tvb, byte_offset) > datalen) { data = tvb_get_ptr(tvb, byte_offset, datalen + 1); + /* shift tvb data bit_offset bits to the left */ + for (i = 0; i < datalen; i++) + buf[i] = (data[i] << left) | (data[i+1] >> right); } else { data = tvb_get_ptr(tvb, byte_offset, datalen); - datalen--; /* correct 'datalen' for 'for' loop */ - buf[datalen] = data[datalen] << left; /* set last octet */ + /* shift tvb data bit_offset bits to the left */ + for (i = 0; i < (datalen-1); i++) + buf[i] = (data[i] << left) | (data[i+1] >> right); + buf[datalen-1] = data[datalen] << left; /* set last octet */ } - /* shift tvb data bit_offset bits to the left */ - for (i = 0; i < datalen; i++) - buf[i] = (data[i] << left) | (data[i+1] >> right); + buf[datalen-1] &= left_aligned_bitmask[remaining_bits]; sub_tvb = tvb_new_child_real_data(tvb, buf, datalen, datalen); -- cgit v1.2.1