diff options
author | Anders Broman <anders.broman@ericsson.com> | 2011-09-26 17:19:54 +0000 |
---|---|---|
committer | Anders Broman <anders.broman@ericsson.com> | 2011-09-26 17:19:54 +0000 |
commit | 75b86a9cd453c39889b27b3701135f64062f41f9 (patch) | |
tree | 5aa3c6d248ed66f7123d038615ac2027f43aa314 /epan/tvbuff.c | |
parent | 03a6c7fe7df40602f0017672732a75c4e64e48a6 (diff) |
From Pascal Quantin:
When building the last byte, the remaining number of bits isn't masked.
svn path=/trunk/; revision=39152
Diffstat (limited to 'epan/tvbuff.c')
-rw-r--r-- | epan/tvbuff.c | 32 |
1 files changed, 25 insertions, 7 deletions
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); |