Qt: Reload Lua expert infos

Support reloading Lua plugins with expert infos.
Use the same delayed deregister logic as for fields.

Change-Id: I36efa0820050b3a7afed4de7a8b0fa16805e8dfa
Reviewed-on: https://code.wireshark.org/review/12498
Petri-Dish: Stig Bjørlykke <stig@bjorlykke.org>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
Stig Bjørlykke 2015-12-10 14:10:17 +01:00 committed by Anders Broman
parent 9c47cb4254
commit ea1789f925
5 changed files with 55 additions and 5 deletions

View File

@ -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)
{
wmem_free(wmem_epan_scope(), module);
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)
{
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

View File

@ -171,11 +171,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

View File

@ -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();

View File

@ -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");
}

View File

@ -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);
}