aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
Diffstat (limited to 'epan')
-rw-r--r--epan/expert.c40
-rw-r--r--epan/expert.h10
-rw-r--r--epan/proto.c3
-rw-r--r--epan/wslua/wslua_proto.c3
-rw-r--r--epan/wslua/wslua_proto_expert.c4
5 files changed, 55 insertions, 5 deletions
diff --git a/epan/expert.c b/epan/expert.c
index 4a3d692f06..6802997d32 100644
--- a/epan/expert.c
+++ b/epan/expert.c
@@ -68,6 +68,9 @@ static gpa_expertinfo_t gpa_expertinfo;
/* Hash table of abbreviations and IDs */
static GHashTable *gpa_name_map = NULL;
+/* Deregistered expert infos */
+static GPtrArray *deregistered_expertinfos = NULL;
+
const value_string expert_group_vals[] = {
{ PI_CHECKSUM, "Checksum" },
{ PI_SEQUENCE, "Sequence" },
@@ -187,6 +190,7 @@ static void uat_expert_post_update_cb(void)
if((guint)eiindex >= gpa_expertinfo.len && getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG")) \
g_error("Unregistered expert info! index=%d", eiindex); \
DISSECTOR_ASSERT_HINT((guint)eiindex < gpa_expertinfo.len, "Unregistered expert info!"); \
+ DISSECTOR_ASSERT_HINT(gpa_expertinfo.ei[eiindex] != NULL, "Unregistered expert info!"); \
expinfo = gpa_expertinfo.ei[eiindex];
void
@@ -265,6 +269,7 @@ expert_init(void)
gpa_expertinfo.ei = NULL;
gpa_name_map = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
uat_saved_fields = g_array_new(FALSE, FALSE, sizeof(expert_field_info*));
+ deregistered_expertinfos = g_ptr_array_new();
}
void
@@ -293,6 +298,11 @@ expert_cleanup(void)
g_array_free(uat_saved_fields, TRUE);
uat_saved_fields = NULL;
}
+
+ if (deregistered_expertinfos) {
+ g_ptr_array_free(deregistered_expertinfos, FALSE);
+ deregistered_expertinfos = NULL;
+ }
}
@@ -323,9 +333,35 @@ expert_module_t *expert_register_protocol(int id)
return module;
}
-void expert_deregister_protocol (expert_module_t *module)
+void
+expert_deregister_expertinfo (const char *abbrev)
+{
+ expert_field_info *expinfo = (expert_field_info*)g_hash_table_lookup(gpa_name_map, abbrev);
+ if (expinfo) {
+ g_ptr_array_add(deregistered_expertinfos, gpa_expertinfo.ei[expinfo->id]);
+ g_hash_table_steal(gpa_name_map, abbrev);
+ }
+}
+
+void
+expert_deregister_protocol (expert_module_t *module)
+{
+ wmem_free(wmem_epan_scope(), module);
+}
+
+static void
+free_deregistered_expertinfo (gpointer data, gpointer user_data _U_)
+{
+ expert_field_info *expinfo = (expert_field_info *) data;
+ gpa_expertinfo.ei[expinfo->id] = NULL; /* Invalidate this id */
+}
+
+void
+expert_free_deregistered_expertinfos (void)
{
- wmem_free(wmem_epan_scope(), module);
+ g_ptr_array_foreach(deregistered_expertinfos, free_deregistered_expertinfo, NULL);
+ g_ptr_array_free(deregistered_expertinfos, TRUE);
+ deregistered_expertinfos = g_ptr_array_new();
}
static int
diff --git a/epan/expert.h b/epan/expert.h
index fabe2f67d3..bf5fcdb1ee 100644
--- a/epan/expert.h
+++ b/epan/expert.h
@@ -172,11 +172,21 @@ proto_tree_add_expert_format(proto_tree *tree, packet_info *pinfo, expert_field
WS_DLL_PUBLIC expert_module_t *expert_register_protocol(int id);
/**
+ * Deregister a expert info.
+ */
+void expert_deregister_expertinfo (const char *abbrev);
+
+/**
* Deregister expert info from a protocol.
*/
WS_DLL_PUBLIC void expert_deregister_protocol (expert_module_t *module);
/**
+ * Free deregistered expert infos.
+ */
+void expert_free_deregistered_expertinfos (void);
+
+/**
* Get summary text of an expert_info field.
* This is intended for use in expert_add_info_format or proto_tree_add_expert_format
* to get the "base" string to then append additional information
diff --git a/epan/proto.c b/epan/proto.c
index 28d3677f5e..783af76eea 100644
--- a/epan/proto.c
+++ b/epan/proto.c
@@ -5400,6 +5400,7 @@ proto_deregister_protocol(const char *short_name)
for (i = 0; i < protocol->fields->len; i++) {
hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i);
hfinfo_remove_from_gpa_name_map(hfinfo);
+ expert_deregister_expertinfo(hfinfo->abbrev);
g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
}
g_ptr_array_free(protocol->fields, TRUE);
@@ -5919,6 +5920,8 @@ free_deregistered_data (gpointer data, gpointer user_data _U_)
void
proto_free_deregistered_fields (void)
{
+ expert_free_deregistered_expertinfos();
+
g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL);
g_ptr_array_free(deregistered_fields, TRUE);
deregistered_fields = g_ptr_array_new();
diff --git a/epan/wslua/wslua_proto.c b/epan/wslua/wslua_proto.c
index 1b3c854586..e2fe16f5c8 100644
--- a/epan/wslua/wslua_proto.c
+++ b/epan/wslua/wslua_proto.c
@@ -715,6 +715,9 @@ int Proto_commit(lua_State* L) {
eiri.eiinfo.severity = e->severity;
eiri.eiinfo.summary = e->text;
+ /* Copy this because it will be free'd when deregistering fields */
+ eiri.eiinfo.hf_info.hfinfo.name = g_strdup(eiri.eiinfo.hf_info.hfinfo.name);
+
if (e->ids.ei != EI_INIT_EI || e->ids.hf != EI_INIT_HF) {
return luaL_error(L,"expert fields can be registered only once");
}
diff --git a/epan/wslua/wslua_proto_expert.c b/epan/wslua/wslua_proto_expert.c
index 8a8079152c..e2d0452bce 100644
--- a/epan/wslua/wslua_proto_expert.c
+++ b/epan/wslua/wslua_proto_expert.c
@@ -70,7 +70,7 @@ WSLUA_CONSTRUCTOR ProtoExpert_new(lua_State* L) {
pe->ids.ei = EI_INIT_EI;
pe->ids.hf = EI_INIT_HF;
- pe->abbrev = g_strdup(abbr);
+ pe->abbrev = g_strdup(abbr);
pe->text = g_strdup(text);
pe->group = group;
pe->severity = severity;
@@ -101,8 +101,6 @@ static int ProtoExpert__gc(lua_State* L) {
if (pe->ids.hf == -2) {
/* Only free unregistered and deregistered ProtoExpert */
- g_free((gchar *)pe->abbrev);
- g_free((gchar *)pe->text);
g_free(pe);
}