aboutsummaryrefslogtreecommitdiffstats
path: root/epan/tvbuff.c
diff options
context:
space:
mode:
authorAnders Broman <anders.broman@ericsson.com>2011-09-26 17:19:54 +0000
committerAnders Broman <anders.broman@ericsson.com>2011-09-26 17:19:54 +0000
commit75b86a9cd453c39889b27b3701135f64062f41f9 (patch)
tree5aa3c6d248ed66f7123d038615ac2027f43aa314 /epan/tvbuff.c
parent03a6c7fe7df40602f0017672732a75c4e64e48a6 (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.c32
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);