wslua: Fix memleak of unregistered ProtoExpert

If a ProtoExpert object was created, but not linked to a Proto, then the
object and some fields (abbrev, text) would leak.

This is a follow-up to g79fef2ae.

Change-Id: Ic0b44e8b70895a19d9b52a0e44064a1e76a58fa0
Reviewed-on: https://code.wireshark.org/review/34876
Petri-Dish: Stig Bjørlykke <stig@bjorlykke.org>
Tested-by: Petri Dish Buildbot
Reviewed-by: Roland Knall <rknall@gmail.com>
This commit is contained in:
Stig Bjørlykke 2019-10-28 15:11:15 +01:00 committed by Roland Knall
parent e8265fbfe3
commit 541afedfbc
2 changed files with 20 additions and 4 deletions

View File

@ -649,6 +649,11 @@ int wslua_deregister_protocols(lua_State* L) {
lua_rawgeti(L, LUA_REGISTRYINDEX, proto->expert_info_table_ref);
for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
ProtoExpert pe = checkProtoExpert(L,-1);
/* Memory ownership was previously transferred to epan in Proto_commit */
pe->abbrev = NULL;
pe->text = NULL;
pe->ids.hf = -2; /* Deregister ProtoExpert, freed in ProtoExpert__gc */
}
lua_pop(L, 1);
@ -749,10 +754,11 @@ int Proto_commit(lua_State* L) {
eiri.eiinfo.severity = e->severity;
eiri.eiinfo.summary = e->text;
if (e->ids.ei != EI_INIT_EI || e->ids.hf != EI_INIT_HF) {
if (e->ids.ei != EI_INIT_EI || e->ids.hf != -2) {
return luaL_error(L,"expert fields can be registered only once");
}
e->ids.hf = -1;
g_array_append_val(proto->eia,eiri);
}

View File

@ -110,7 +110,7 @@ WSLUA_CONSTRUCTOR ProtoExpert_new(lua_State* L) {
pe = g_new(wslua_expert_field_t,1);
pe->ids.ei = EI_INIT_EI;
pe->ids.hf = EI_INIT_HF;
pe->ids.hf = -2;
pe->abbrev = g_strdup(abbr);
pe->text = g_strdup(text);
pe->group = group;
@ -140,11 +140,21 @@ WSLUA_METAMETHOD ProtoExpert__tostring(lua_State* L) {
static int ProtoExpert__gc(lua_State* L) {
ProtoExpert pe = toProtoExpert(L,1);
if (pe->ids.hf == -2) {
/*
* Initialized to -2 in ProtoExpert_new,
* changed to -1 in Proto_commit and subsequently replaced by
* an allocated number in proto_register_field_array.
* Reset to -2 again in wslua_deregister_protocols.
*/
if (pe->ids.hf != -2) {
/* Only free unregistered and deregistered ProtoExpert */
g_free(pe);
return 0;
}
g_free((gchar *)pe->abbrev);
g_free((gchar *)pe->text);
g_free(pe);
return 0;
}