diff options
-rw-r--r-- | epan/dissectors/packet-ber.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/epan/dissectors/packet-ber.c b/epan/dissectors/packet-ber.c index b03fee175e..8cd173ba56 100644 --- a/epan/dissectors/packet-ber.c +++ b/epan/dissectors/packet-ber.c @@ -4035,6 +4035,7 @@ dissect_ber_constrained_bitstring(gboolean implicit_tag, asn1_ctx_t *actx, proto item = proto_tree_add_item(parent_tree, hf_id, tvb, offset, len, ENC_NA); actx->created_item = item; if (named_bits) { + guint8 *bitstring = (guint8 *)tvb_memdup(wmem_packet_scope(), tvb, offset, len); const int named_bits_bytelen = (num_named_bits + 7) / 8; if (show_internal_ber_fields) { guint zero_bits_omitted = 0; @@ -4047,13 +4048,6 @@ dissect_ber_constrained_bitstring(gboolean implicit_tag, asn1_ctx_t *actx, proto tree = proto_item_add_subtree(item, ett_id); } for (int i = 0; i < named_bits_bytelen; i++) { - // If less data is available than the number of named bits, then - // the trailing (right) bits are assumed to be 0. - guint64 value = 0; - if (i < len) { - value = tvb_get_guint8(tvb, offset + i); - } - // Process 8 bits at a time instead of 64, each field masks a // single byte. const int bit_offset = 8 * i; @@ -4065,6 +4059,18 @@ dissect_ber_constrained_bitstring(gboolean implicit_tag, asn1_ctx_t *actx, proto section_named_bits = (const int** )flags; } + // If less data is available than the number of named bits, then + // the trailing (right) bits are assumed to be 0. + guint64 value = 0; + if (i < len) { + value = bitstring[i]; + if (num_named_bits - bit_offset > 7) { + bitstring[i] = 0; + } else { + bitstring[i] &= 0xff >> (num_named_bits - bit_offset); + } + } + // TODO should non-zero pad bits be masked from the value? // When trailing zeroes are not present in the data, mark the // last byte for the lack of a better alternative. @@ -4072,9 +4078,12 @@ dissect_ber_constrained_bitstring(gboolean implicit_tag, asn1_ctx_t *actx, proto } // If more data is available than the number of named bits, then // either the spec was updated or the packet is malformed. - if (named_bits_bytelen < len) { - expert_add_info_format(actx->pinfo, item, &ei_ber_bits_unknown, "Unknown bit(s): 0x%s", - tvb_bytes_to_str(wmem_packet_scope(), tvb, offset + named_bits_bytelen, len - named_bits_bytelen)); + for (int i = 0; i < len; i++) { + if (bitstring[i]) { + expert_add_info_format(actx->pinfo, item, &ei_ber_bits_unknown, "Unknown bit(s): 0x%s", + bytes_to_str(wmem_packet_scope(), bitstring, len)); + break; + } } } } |