diff options
author | Guy Harris <guy@alum.mit.edu> | 2019-06-08 01:08:11 -0700 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2019-06-08 09:11:22 +0000 |
commit | 1c601c204a26a3d4b49225bfa198eaee379e564e (patch) | |
tree | 4730332817d9816689e2066def26dcbb5a545ec3 /epan/proto.c | |
parent | cf9f46c5f59dce4c528f6608a7dfffb7c1fbfb5a (diff) |
Have routines to add a protocol tree item and return a display string.
That way, even if we're not building a protocol tree, so that you don't
get protocol tree items, you can get the display string, e.g. to use in
a column.
Replace the use of the "get display string" routines with calls to those
routines.
Change-Id: I23e3e88838bdf837d8660c271f78c79b7d1c5620
Reviewed-on: https://code.wireshark.org/review/33519
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'epan/proto.c')
-rw-r--r-- | epan/proto.c | 319 |
1 files changed, 203 insertions, 116 deletions
diff --git a/epan/proto.c b/epan/proto.c index 1522b275fa..d22959611a 100644 --- a/epan/proto.c +++ b/epan/proto.c @@ -1004,6 +1004,96 @@ proto_registrar_get_id_byname(const char *field_name) } +static char * +hfinfo_format_text(wmem_allocator_t *scope, const header_field_info *hfinfo, + const guchar *string) +{ + switch (hfinfo->display) { + case STR_ASCII: + return format_text(scope, string, strlen(string)); +/* + case STR_ASCII_WSP + return format_text_wsp(string, strlen(string)); + */ + case STR_UNICODE: + /* XXX, format_unicode_text() */ + return wmem_strdup(scope, string); + } + + return format_text(scope, string, strlen(string)); +} + +static char * +hfinfo_format_bytes(wmem_allocator_t *scope, const header_field_info *hfinfo, + const guint8 *bytes, guint length) +{ + char *str = NULL; + const guint8 *p; + gboolean is_printable; + + if (bytes) { + if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE) { + /* + * Check whether all bytes are printable. + */ + is_printable = TRUE; + for (p = bytes; p < bytes+length; p++) { + if (!g_ascii_isprint(*p)) { + /* Not printable. */ + is_printable = FALSE; + break; + } + } + + /* + * If all bytes are printable ASCII, show the bytes + * as a string - in quotes to indicate that it's + * a string. + */ + if (is_printable) { + str = wmem_strdup_printf(scope, "\"%.*s\"", + (int)length, bytes); + return str; + } + } + + /* + * Either it's not printable ASCII, or we don't care whether + * it's printable ASCII; show it as hex bytes. + */ + switch (FIELD_DISPLAY(hfinfo->display)) { + case SEP_DOT: + str = bytestring_to_str(scope, bytes, length, '.'); + break; + case SEP_DASH: + str = bytestring_to_str(scope, bytes, length, '-'); + break; + case SEP_COLON: + str = bytestring_to_str(scope, bytes, length, ':'); + break; + case SEP_SPACE: + str = bytestring_to_str(scope, bytes, length, ' '); + break; + case BASE_NONE: + default: + if (prefs.display_byte_fields_with_spaces) { + str = bytestring_to_str(scope, bytes, length, ' '); + } else { + str = bytes_to_str(scope, bytes, length); + } + break; + } + } + else { + if (hfinfo->display & BASE_ALLOW_ZERO) { + str = wmem_strdup(scope, "<none>"); + } else { + str = wmem_strdup(scope, "<MISSING>"); + } + } + return str; +} + static void ptvcursor_new_subtree_levels(ptvcursor_t *ptvc) { @@ -3321,6 +3411,119 @@ proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, tvb, start, length, encoding, scope, retval, &length); } +proto_item * +proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex, + tvbuff_t *tvb, + const gint start, gint length, + const guint encoding, + wmem_allocator_t *scope, + char **retval, + gint *lenretval) +{ + proto_item *pi; + header_field_info *hfinfo = proto_registrar_get_nth(hfindex); + field_info *new_fi; + const guint8 *value; + guint32 n = 0; + + DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!"); + + switch (hfinfo->type) { + case FT_STRING: + value = get_string_value(scope, tvb, start, length, lenretval, encoding); + *retval = hfinfo_format_text(scope, hfinfo, value);; + break; + case FT_STRINGZ: + value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding); + *retval = hfinfo_format_text(scope, hfinfo, value);; + break; + case FT_UINT_STRING: + value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding); + *retval = hfinfo_format_text(scope, hfinfo, value);; + break; + case FT_STRINGZPAD: + value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding); + *retval = hfinfo_format_text(scope, hfinfo, value);; + break; + case FT_BYTES: + value = tvb_get_ptr(tvb, start, length); + *retval = hfinfo_format_bytes(scope, hfinfo, value, length); + if (lenretval) + *lenretval = length; + break; + case FT_UINT_BYTES: + n = get_uint_value(tree, tvb, start, length, encoding); + value = tvb_get_ptr(tvb, start + length, n); + *retval = hfinfo_format_bytes(scope, hfinfo, value, n); + if (lenretval) + *lenretval = length + n; + break; + default: + REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, FT_BYTES, or FT_UINT_BYTES", + hfinfo->abbrev); + } + + CHECK_FOR_NULL_TREE(tree); + + TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo); + + new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval); + + switch (hfinfo->type) { + + case FT_STRING: + case FT_STRINGZ: + case FT_UINT_STRING: + case FT_STRINGZPAD: + proto_tree_set_string(new_fi, value); + break; + + case FT_BYTES: + proto_tree_set_bytes(new_fi, value, length); + break; + + case FT_UINT_BYTES: + proto_tree_set_bytes(new_fi, value, n); + break; + default: + g_assert_not_reached(); + } + + new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN; + + pi = proto_tree_add_node(tree, new_fi); + + switch (hfinfo->type) { + + case FT_STRING: + case FT_STRINGZ: + case FT_UINT_STRING: + case FT_STRINGZPAD: + detect_trailing_stray_characters(hfinfo->type, encoding, value, length, pi); + break; + + case FT_BYTES: + case FT_UINT_BYTES: + break; + + default: + g_assert_not_reached(); + } + + return pi; +} + +proto_item * +proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex, + tvbuff_t *tvb, + const gint start, gint length, + const guint encoding, + wmem_allocator_t *scope, + char **retval) +{ + return proto_tree_add_item_ret_display_string_and_length(tree, hfindex, + tvb, start, length, encoding, scope, retval, &length); +} /* Gets data from tvbuff, adds it to proto_tree, increments offset, and returns proto_item* */ @@ -5733,96 +5936,6 @@ proto_tree_set_representation(proto_item *pi, const char *format, va_list ap) } } -static char * -hfinfo_format_text(wmem_allocator_t *scope, const header_field_info *hfinfo, - const guchar *string) -{ - switch (hfinfo->display) { - case STR_ASCII: - return format_text(scope, string, strlen(string)); -/* - case STR_ASCII_WSP - return format_text_wsp(string, strlen(string)); - */ - case STR_UNICODE: - /* XXX, format_unicode_text() */ - return wmem_strdup(scope, string); - } - - return format_text(scope, string, strlen(string)); -} - -static char * -hfinfo_format_bytes(wmem_allocator_t *scope, const header_field_info *hfinfo, - guint8 *bytes, guint length) -{ - char *str = NULL; - guint8 *p; - gboolean is_printable; - - if (bytes) { - if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE) { - /* - * Check whether all bytes are printable. - */ - is_printable = TRUE; - for (p = bytes; p < bytes+length; p++) { - if (!g_ascii_isprint(*p)) { - /* Not printable. */ - is_printable = FALSE; - break; - } - } - - /* - * If all bytes are printable ASCII, show the bytes - * as a string - in quotes to indicate that it's - * a string. - */ - if (is_printable) { - str = wmem_strdup_printf(scope, "\"%.*s\"", - (int)length, bytes); - return str; - } - } - - /* - * Either it's not printable ASCII, or we don't care whether - * it's printable ASCII; show it as hex bytes. - */ - switch (FIELD_DISPLAY(hfinfo->display)) { - case SEP_DOT: - str = bytestring_to_str(scope, bytes, length, '.'); - break; - case SEP_DASH: - str = bytestring_to_str(scope, bytes, length, '-'); - break; - case SEP_COLON: - str = bytestring_to_str(scope, bytes, length, ':'); - break; - case SEP_SPACE: - str = bytestring_to_str(scope, bytes, length, ' '); - break; - case BASE_NONE: - default: - if (prefs.display_byte_fields_with_spaces) { - str = bytestring_to_str(scope, bytes, length, ' '); - } else { - str = bytes_to_str(scope, bytes, length); - } - break; - } - } - else { - if (hfinfo->display & BASE_ALLOW_ZERO) { - str = wmem_strdup(scope, "<none>"); - } else { - str = wmem_strdup(scope, "<MISSING>"); - } - } - return str; -} - static int protoo_strlcpy(gchar *dest, const gchar *src, gsize dest_size) { @@ -12339,32 +12452,6 @@ proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const guint offset, return ti; } -char * -proto_string_item_get_display_string(wmem_allocator_t *scope, proto_item *pi) -{ - field_info *fi = pi->finfo; - header_field_info *hfinfo = fi->hfinfo; - - DISSECTOR_ASSERT(hfinfo->type == FT_STRING || - hfinfo->type == FT_STRINGZ || - hfinfo->type == FT_UINT_STRING || - hfinfo->type == FT_STRINGZPAD); - return hfinfo_format_text(scope, hfinfo, - (guint8 *)fvalue_get(&fi->value)); -} - -char * -proto_bytes_item_get_display_string(wmem_allocator_t *scope, proto_item *pi) -{ - field_info *fi = pi->finfo; - header_field_info *hfinfo = fi->hfinfo; - - DISSECTOR_ASSERT(hfinfo->type == FT_BYTES || - hfinfo->type == FT_UINT_BYTES); - return hfinfo_format_bytes(scope, hfinfo, - (guint8 *)fvalue_get(&fi->value), fvalue_length(&fi->value)); -} - guchar proto_check_field_name(const gchar *field_name) { |