diff options
author | Jaap Keuter <jaap.keuter@xs4all.nl> | 2021-12-23 14:27:30 +0000 |
---|---|---|
committer | Jaap Keuter <jaap.keuter@xs4all.nl> | 2021-12-23 14:27:30 +0000 |
commit | f151e1b0c2521ce838cdee6f32014296185e7dc9 (patch) | |
tree | b1ea38cb8edfeaf422e93e4326af86fcd15b49ff | |
parent | 54e9c99041701f544e5ea58fb484414d5c0bc90a (diff) |
Refactor VARINT handling
-rw-r--r-- | epan/proto.c | 190 | ||||
-rw-r--r-- | epan/tvbuff.c | 18 |
2 files changed, 50 insertions, 158 deletions
diff --git a/epan/proto.c b/epan/proto.c index 1734dbf0a2..74c3447d52 100644 --- a/epan/proto.c +++ b/epan/proto.c @@ -209,8 +209,6 @@ static void fill_label_boolean(field_info *fi, gchar *label_str); static void fill_label_bitfield_char(field_info *fi, gchar *label_str); static void fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed); static void fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed); -static void fill_label_bitfield_varint(field_info *fi, gchar *label_str, gboolean is_signed); -static void fill_label_bitfield_varint64(field_info *fi, gchar *label_str, gboolean is_signed); static void fill_label_char(field_info *fi, gchar *label_str); static void fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed); static void fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed); @@ -2607,17 +2605,12 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree, case FT_UINT16: case FT_UINT24: case FT_UINT32: - if (encoding & ENC_VARINT_PROTOBUF) { + if (encoding & ENC_VARINT_MASK) { new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding); - new_fi->flags |= FI_VARINT; - value = (guint32)value64; - } else if (encoding & ENC_VARINT_QUIC) { - new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding); - value = (guint32)value64; - } else if (encoding & ENC_VARINT_ZIGZAG) { - new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding); - new_fi->flags |= FI_VARINT; value = (guint32)value64; + if (!(encoding & ENC_VARINT_QUIC)) { + new_fi->flags |= FI_VARINT; + } } else { /* @@ -2636,15 +2629,11 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree, case FT_UINT48: case FT_UINT56: case FT_UINT64: - - if (encoding & ENC_VARINT_PROTOBUF) { - new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding); - new_fi->flags |= FI_VARINT; - } else if (encoding & ENC_VARINT_QUIC) { + if (encoding & ENC_VARINT_MASK) { new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding); - } else if (encoding & ENC_VARINT_ZIGZAG) { - new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding); - new_fi->flags |= FI_VARINT; + if (!(encoding & ENC_VARINT_QUIC)) { + new_fi->flags |= FI_VARINT; + } } else { /* @@ -5214,11 +5203,10 @@ proto_tree_set_boolean(field_info *fi, guint64 value) static char * other_decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width) { - int i; + int i = 0; guint64 bit; char *p; - i = 0; p = buf; /* This is a devel error. It is safer to stop here. */ @@ -5266,6 +5254,10 @@ other_decode_bitfield_varint_value(char *buf, guint64 val, guint64 mask, const i char *p; p = buf; + + /* This is a devel error. It is safer to stop here. */ + DISSECTOR_ASSERT(width >= 1); + bit = G_GUINT64_CONSTANT(1) << (width - 1); for (;;) { if (((8-(i % 8)) != 8) && /* MSB is never used for value. */ @@ -9049,11 +9041,7 @@ proto_item_fill_label(field_info *fi, gchar *label_str) case FT_UINT24: case FT_UINT32: if (hfinfo->bitmask) { - if (fi->flags & FI_VARINT) { - fill_label_bitfield_varint(fi, label_str, FALSE); - } else { - fill_label_bitfield(fi, label_str, FALSE); - } + fill_label_bitfield(fi, label_str, FALSE); } else { fill_label_number(fi, label_str, FALSE); } @@ -9068,11 +9056,7 @@ proto_item_fill_label(field_info *fi, gchar *label_str) case FT_UINT56: case FT_UINT64: if (hfinfo->bitmask) { - if (fi->flags & FI_VARINT) { - fill_label_bitfield_varint64(fi, label_str, FALSE); - } else { - fill_label_bitfield64(fi, label_str, FALSE); - } + fill_label_bitfield64(fi, label_str, FALSE); } else { fill_label_number64(fi, label_str, FALSE); } @@ -9083,11 +9067,7 @@ proto_item_fill_label(field_info *fi, gchar *label_str) case FT_INT24: case FT_INT32: if (hfinfo->bitmask) { - if (fi->flags & FI_VARINT) { - fill_label_bitfield_varint(fi, label_str, TRUE); - } else { - fill_label_bitfield(fi, label_str, TRUE); - } + fill_label_bitfield(fi, label_str, TRUE); } else { fill_label_number(fi, label_str, TRUE); } @@ -9098,11 +9078,7 @@ proto_item_fill_label(field_info *fi, gchar *label_str) case FT_INT56: case FT_INT64: if (hfinfo->bitmask) { - if (fi->flags & FI_VARINT) { - fill_label_bitfield_varint64(fi, label_str, TRUE); - } else { - fill_label_bitfield64(fi, label_str, TRUE); - } + fill_label_bitfield64(fi, label_str, TRUE); } else { fill_label_number64(fi, label_str, TRUE); } @@ -9473,16 +9449,17 @@ fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed) { char *p; int bitfield_byte_length, bitwidth; - guint32 unshifted_value; - guint32 value; - + guint32 value, unshifted_value; char buf[32]; const char *out; header_field_info *hfinfo = fi->hfinfo; /* Figure out the bit width */ - bitwidth = hfinfo_container_bitwidth(hfinfo); + if (fi->flags & FI_VARINT) + bitwidth = fi->length*8; + else + bitwidth = hfinfo_container_bitwidth(hfinfo); /* Un-shift bits */ if (is_signed) @@ -9496,7 +9473,10 @@ fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed) } /* Create the bitfield first */ - p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth); + if (fi->flags & FI_VARINT) + p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth); + else + p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth); bitfield_byte_length = (int) (p - label_str); /* Fill in the textual info using stored (shifted) value */ @@ -9529,16 +9509,17 @@ fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed) { char *p; int bitfield_byte_length, bitwidth; - guint64 unshifted_value; - guint64 value; - + guint64 value, unshifted_value; char buf[48]; const char *out; header_field_info *hfinfo = fi->hfinfo; /* Figure out the bit width */ - bitwidth = hfinfo_container_bitwidth(hfinfo); + if (fi->flags & FI_VARINT) + bitwidth = fi->length*8; + else + bitwidth = hfinfo_container_bitwidth(hfinfo); /* Un-shift bits */ if (is_signed) @@ -9552,111 +9533,10 @@ fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed) } /* Create the bitfield first */ - p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth); - bitfield_byte_length = (int) (p - label_str); - - /* Fill in the textual info using stored (shifted) value */ - if (hfinfo->display == BASE_CUSTOM) { - gchar tmp[ITEM_LABEL_LENGTH]; - const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings; - - DISSECTOR_ASSERT(fmtfunc64); - fmtfunc64(tmp, value); - label_fill(label_str, bitfield_byte_length, hfinfo, tmp); - } - else if (hfinfo->strings) { - const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown"); - - out = hfinfo_number_vals_format64(hfinfo, buf, value); - if (out == NULL) /* BASE_NONE so don't put integer in descr */ - label_fill(label_str, bitfield_byte_length, hfinfo, val_str); - else - label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out); - } - else { - out = hfinfo_number_value_format64(hfinfo, buf, value); - - label_fill(label_str, bitfield_byte_length, hfinfo, out); - } -} - -static void -fill_label_bitfield_varint(field_info *fi, gchar *label_str, gboolean is_signed) -{ - char *p; - int bitfield_byte_length; - guint32 value, unshifted_value; - char buf[48]; - const char *out; - - header_field_info *hfinfo = fi->hfinfo; - - /* Un-shift bits */ - if (is_signed) { - value = fvalue_get_sinteger(&fi->value); - } else { - value = fvalue_get_uinteger(&fi->value); - } - unshifted_value = value; - if (hfinfo->bitmask) { - unshifted_value <<= hfinfo_bitshift(hfinfo); - } - - /* Create the bitfield first */ - p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, fi->length*8); - bitfield_byte_length = (int) (p - label_str); - - /* Fill in the textual info using stored (shifted) value */ - if (hfinfo->display == BASE_CUSTOM) { - gchar tmp[ITEM_LABEL_LENGTH]; - const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings; - - DISSECTOR_ASSERT(fmtfunc); - fmtfunc(tmp, value); - label_fill(label_str, bitfield_byte_length, hfinfo, tmp); - } - else if (hfinfo->strings) { - const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown"); - - out = hfinfo_number_vals_format(hfinfo, buf, value); - if (out == NULL) /* BASE_NONE so don't put integer in descr */ - label_fill(label_str, bitfield_byte_length, hfinfo, val_str); - else - label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out); - } - else { - out = hfinfo_number_value_format(hfinfo, buf, value); - - label_fill(label_str, bitfield_byte_length, hfinfo, out); - } -} - -static void -fill_label_bitfield_varint64(field_info *fi, gchar *label_str, gboolean is_signed) -{ - char *p; - int bitfield_byte_length; - guint64 unshifted_value; - guint64 value; - - char buf[48]; - const char *out; - - header_field_info *hfinfo = fi->hfinfo; - - /* Un-shift bits */ - if (is_signed) { - value = fvalue_get_sinteger64(&fi->value); - } else { - value = fvalue_get_uinteger64(&fi->value); - } - unshifted_value = value; - if (hfinfo->bitmask) { - unshifted_value <<= hfinfo_bitshift(hfinfo); - } - - /* Create the bitfield first */ - p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, fi->length*8); + if (fi->flags & FI_VARINT) + p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth); + else + p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth); bitfield_byte_length = (int) (p - label_str); /* Fill in the textual info using stored (shifted) value */ diff --git a/epan/tvbuff.c b/epan/tvbuff.c index 26f69cf473..9c411fdad3 100644 --- a/epan/tvbuff.c +++ b/epan/tvbuff.c @@ -4486,7 +4486,9 @@ tvb_get_varint(tvbuff_t *tvb, guint offset, guint maxlen, guint64 *value, const { *value = 0; - if (encoding & ENC_VARINT_PROTOBUF) { + switch (encoding & ENC_VARINT_MASK) { + case ENC_VARINT_PROTOBUF: + { guint i; guint64 b; /* current byte */ @@ -4499,7 +4501,11 @@ tvb_get_varint(tvbuff_t *tvb, guint offset, guint maxlen, guint64 *value, const return i + 1; } } - } else if (encoding & ENC_VARINT_ZIGZAG) { + break; + } + + case ENC_VARINT_ZIGZAG: + { guint i; guint64 b; /* current byte */ @@ -4513,9 +4519,11 @@ tvb_get_varint(tvbuff_t *tvb, guint offset, guint maxlen, guint64 *value, const return i + 1; } } + break; } - else if (encoding & ENC_VARINT_QUIC) { + case ENC_VARINT_QUIC: + { /* calculate variable length */ *value = tvb_get_guint8(tvb, offset); switch((*value) >> 6) { @@ -4535,7 +4543,11 @@ tvb_get_varint(tvbuff_t *tvb, guint offset, guint maxlen, guint64 *value, const ws_assert_not_reached(); break; } + break; + } + default: + DISSECTOR_ASSERT_NOT_REACHED(); } return 0; /* 10 bytes scanned, but no bytes' msb is zero */ |