diff options
author | Stig Bjørlykke <stig@bjorlykke.org> | 2019-10-28 09:52:12 +0100 |
---|---|---|
committer | Roland Knall <rknall@gmail.com> | 2019-10-28 15:05:54 +0000 |
commit | 551745998ef4a9352bca2a0035780bc1a96e55eb (patch) | |
tree | 8476113202bfff9b4fd37038bb1c6a3173295cd2 /epan/proto.c | |
parent | 5fb897077e77c43d0080618d338443a8d62e5663 (diff) |
wslua: Fix memleak of unregistered ProtoField strings
If a ProtoField object was created, but not linked to a Proto, then the
strings field and all elements (depending on type) would leak.
This is a follow-up to g79fef2ae and fixes the real issue in g44870fb1.
Change-Id: I01880a92bb20fae45f68c754b07daeb07630deec
Reviewed-on: https://code.wireshark.org/review/34872
Petri-Dish: Stig Bjørlykke <stig@bjorlykke.org>
Tested-by: Petri Dish Buildbot
Reviewed-by: Vasil Velichkov <vvvelichkov@gmail.com>
Reviewed-by: Roland Knall <rknall@gmail.com>
Diffstat (limited to 'epan/proto.c')
-rw-r--r-- | epan/proto.c | 172 |
1 files changed, 90 insertions, 82 deletions
diff --git a/epan/proto.c b/epan/proto.c index 70ccbfa641..968ced5aae 100644 --- a/epan/proto.c +++ b/epan/proto.c @@ -7675,6 +7675,95 @@ proto_add_deregistered_data (void *data) g_ptr_array_add(deregistered_data, data); } +void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings) +{ + if (field_strings == NULL) { + return; + } + + switch (field_type) { + case FT_FRAMENUM: + /* This is just an integer represented as a pointer */ + break; + case FT_PROTOCOL: { + protocol_t *protocol = (protocol_t *)field_strings; + g_free((gchar *)protocol->short_name); + break; + } + case FT_BOOLEAN: { + true_false_string *tf = (true_false_string *)field_strings; + g_free((gchar *)tf->true_string); + g_free((gchar *)tf->false_string); + break; + } + case FT_UINT40: + case FT_INT40: + case FT_UINT48: + case FT_INT48: + case FT_UINT56: + case FT_INT56: + case FT_UINT64: + case FT_INT64: { + /* + * XXX - if it's BASE_RANGE_STRING, or + * BASE_EXT_STRING, should we free it? + */ + if (field_display & BASE_UNIT_STRING) { + unit_name_string *unit = (unit_name_string *)field_strings; + g_free((gchar *)unit->singular); + g_free((gchar *)unit->plural); + } else { + val64_string *vs64 = (val64_string *)field_strings; + while (vs64->strptr) { + g_free((gchar *)vs64->strptr); + vs64++; + } + } + break; + } + case FT_CHAR: + case FT_UINT8: + case FT_INT8: + case FT_UINT16: + case FT_INT16: + case FT_UINT24: + case FT_INT24: + case FT_UINT32: + case FT_INT32: + case FT_FLOAT: + case FT_DOUBLE: { + /* + * XXX - if it's BASE_RANGE_STRING, or + * BASE_EXT_STRING, should we free it? + */ + if (field_display & BASE_UNIT_STRING) { + unit_name_string *unit = (unit_name_string *)field_strings; + g_free((gchar *)unit->singular); + g_free((gchar *)unit->plural); + } else if (field_display & BASE_RANGE_STRING) { + range_string *rs = (range_string *)field_strings; + while (rs->strptr) { + g_free((gchar *)rs->strptr); + rs++; + } + } else { + value_string *vs = (value_string *)field_strings; + while (vs->strptr) { + g_free((gchar *)vs->strptr); + vs++; + } + } + break; + default: + break; + } + } + + if (field_type != FT_FRAMENUM) { + g_free((void *)field_strings); + } +} + static void free_deregistered_field (gpointer data, gpointer user_data _U_) { @@ -7685,88 +7774,7 @@ free_deregistered_field (gpointer data, gpointer user_data _U_) g_free((char *)hfi->abbrev); g_free((char *)hfi->blurb); - if (hfi->strings) { - switch (hfi->type) { - case FT_FRAMENUM: - /* This is just an integer represented as a pointer */ - break; - case FT_PROTOCOL: { - protocol_t *protocol = (protocol_t *)hfi->strings; - g_free((gchar *)protocol->short_name); - break; - } - case FT_BOOLEAN: { - true_false_string *tf = (true_false_string *)hfi->strings; - g_free ((gchar *)tf->true_string); - g_free ((gchar *)tf->false_string); - break; - } - case FT_UINT40: - case FT_INT40: - case FT_UINT48: - case FT_INT48: - case FT_UINT56: - case FT_INT56: - case FT_UINT64: - case FT_INT64: { - /* - * XXX - if it's BASE_RANGE_STRING, or - * BASE_EXT_STRING, should we free it? - */ - if (hfi->display & BASE_UNIT_STRING) { - unit_name_string *unit = (unit_name_string*)hfi->strings; - g_free ((gchar *)unit->singular); - g_free ((gchar *)unit->plural); - } else { - val64_string *vs64 = (val64_string *)hfi->strings; - while (vs64->strptr) { - g_free((gchar *)vs64->strptr); - vs64++; - } - } - break; - } - case FT_CHAR: - case FT_UINT8: - case FT_INT8: - case FT_UINT16: - case FT_INT16: - case FT_UINT24: - case FT_INT24: - case FT_UINT32: - case FT_INT32: - case FT_FLOAT: - case FT_DOUBLE: { - /* - * XXX - if it's BASE_RANGE_STRING, or - * BASE_EXT_STRING, should we free it? - */ - if (hfi->display & BASE_UNIT_STRING) { - unit_name_string *unit = (unit_name_string*)hfi->strings; - g_free ((gchar *)unit->singular); - g_free ((gchar *)unit->plural); - } else if (hfi->display & BASE_RANGE_STRING) { - range_string *rs = (range_string *)hfi->strings; - while (rs->strptr) { - g_free((gchar *)rs->strptr); - rs++; - } - } else { - value_string *vs = (value_string *)hfi->strings; - while (vs->strptr) { - g_free((gchar *)vs->strptr); - vs++; - } - } - break; - default: - break; - } - } - if (hfi->type != FT_FRAMENUM) { - g_free((void *)hfi->strings); - } - } + proto_free_field_strings(hfi->type, hfi->display, hfi->strings); if (hfi->parent == -1) g_slice_free(header_field_info, hfi); |