aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-amqp.c
diff options
context:
space:
mode:
authorBill Meier <wmeier@newsguy.com>2014-11-04 11:15:18 -0500
committerBill Meier <wmeier@newsguy.com>2014-11-04 16:22:37 +0000
commit9ac261f205b7b6cba646368433eac550c7a6acd7 (patch)
treee883d9ed2d9aa4975fb7c153e11a08e8d43af490 /epan/dissectors/packet-amqp.c
parentc3c59dc2ad860d08a1adc5fd69fa26f16d61db01 (diff)
amqp: Fix a number of bugs in dissect_amqp_0_10_map().
(Among other things: "2 ^ xxx" is *not* 2 to the xxx'th power). Change-Id: I893b72e853ecbb5d7e6259e950fb347e89eed6c2 Reviewed-on: https://code.wireshark.org/review/5109 Reviewed-by: Bill Meier <wmeier@newsguy.com>
Diffstat (limited to 'epan/dissectors/packet-amqp.c')
-rw-r--r--epan/dissectors/packet-amqp.c60
1 files changed, 35 insertions, 25 deletions
diff --git a/epan/dissectors/packet-amqp.c b/epan/dissectors/packet-amqp.c
index 351b691e36..23f20c7886 100644
--- a/epan/dissectors/packet-amqp.c
+++ b/epan/dissectors/packet-amqp.c
@@ -3051,18 +3051,17 @@ dissect_amqp_0_10_map(tvbuff_t *tvb,
const char *name;
const char *amqp_typename;
const char *value;
- gint field_start, field_length;
guint32 field_count;
type_formatter formatter;
- field_length = 0;
map_tree = proto_item_add_subtree(item, ett_amqp_0_10_map);
field_count = tvb_get_ntohl(tvb, offset);
AMQP_INCREMENT(offset, 4, bound);
length -= 4;
proto_item_append_text(item, " (%d entries)", field_count);
while ((field_count > 0) && (length > 0)) {
- field_start = offset;
+ guint field_length = 0;
+ guint field_start = offset;
namelen = tvb_get_guint8(tvb, offset);
AMQP_INCREMENT(offset, 1, bound);
length -= 1;
@@ -3073,52 +3072,62 @@ dissect_amqp_0_10_map(tvbuff_t *tvb,
AMQP_INCREMENT(offset, 1, bound);
length -= 1;
if (get_amqp_0_10_type_formatter(type, &amqp_typename, &formatter, &size)) {
- field_length = formatter(tvb, offset, bound, size, &value);
+ field_length = formatter(tvb, offset, bound, size, &value); /* includes var 'length' field if var field */
proto_tree_add_none_format(map_tree,
hf_amqp_field,
tvb,
field_start,
- field_length,
+ 1 + namelen + 1 + field_length,
"%s (%s): %s",
name, amqp_typename, value);
AMQP_INCREMENT(offset, field_length, bound);
length -= field_length;
}
- else {
+ else { /* type not found in table: Do special processing */
+ guint size_field_len = 0;
+
switch (type) {
case AMQP_0_10_TYPE_MAP:
case AMQP_0_10_TYPE_LIST:
case AMQP_0_10_TYPE_ARRAY:
field_length = tvb_get_ntohl(tvb, offset);
+ size_field_len = 4;
proto_tree_add_none_format(map_tree, hf_amqp_field,
- tvb, field_start, field_length,
+ tvb, field_start, (1 + namelen + + 1 + 4 + field_length),
"%s (composite): %d bytes",
name, field_length);
- AMQP_INCREMENT(offset, field_length, bound);
- length -= field_length;
break;
- default:
- amqp_typename = "unimplemented";
+ default: { /* Determine total field length from the type */
+ guint temp = 1 << ((type & 0x70) >> 4); /* Hack to map type to a length value */
+ amqp_typename = "unimplemented type";
+
+ /* fixed length cases */
if ((type & 0x80) == 0) {
- field_length = 2 ^ ((type & 0x70) >> 4);
+ field_length = temp; /* Actual length of the field */
+ }
+ else if ((type & 0xc0) == 0xc0) {
+ field_length = 5;
}
else if ((type & 0xd0) == 0xd0) {
field_length = 9;
}
- else if ((type & 0xc0) == 0xc0) {
- field_length = 5;
+ else if ((type & 0xf0) == 0xf0) {
+ field_length = 0;
}
+
+ /* variable length cases */
else if ((type & 0x80) == 0x80) {
- switch (2 ^ ((type & 0x70) >> 4)) {
+ size_field_len = temp;
+ switch (size_field_len) {
case 1:
- field_length += tvb_get_guint8(tvb, offset);
+ field_length = tvb_get_guint8(tvb, offset);
break;
case 2:
- field_length += tvb_get_ntohs(tvb, offset);
+ field_length = tvb_get_ntohs(tvb, offset);
break;
case 4:
- field_length += tvb_get_ntohl(tvb, offset);
+ field_length = tvb_get_ntohl(tvb, offset);
break;
default:
field_length = 1; /* Reserved... skip 1 */
@@ -3127,16 +3136,17 @@ dissect_amqp_0_10_map(tvbuff_t *tvb,
}
}
else {
- field_length = 1; /* Reserved... skip 1 */
- amqp_typename = "reserved";
+ DISSECTOR_ASSERT_NOT_REACHED();
}
proto_tree_add_none_format(map_tree, hf_amqp_field,
- tvb, field_start, field_length,
- "%s (%s): %d bytes",
+ tvb, field_start, 1 + namelen + 1 + size_field_len + field_length,
+ "%s (%s): (value field length: %d bytes)",
name, amqp_typename, field_length);
- AMQP_INCREMENT(offset, field_length, bound);
- length -= field_length;
- }
+ } /* default */
+ } /* switch (type) */
+
+ AMQP_INCREMENT(offset, (size_field_len + field_length), bound);
+ length -= (size_field_len + field_length);
}
field_count -= 1;