diff options
author | Peter Wu <peter@lekensteyn.nl> | 2016-09-11 14:17:14 +0200 |
---|---|---|
committer | Peter Wu <peter@lekensteyn.nl> | 2016-09-12 12:14:46 +0000 |
commit | 26bf66f423489fa3128d406c949954be5c39455c (patch) | |
tree | fb2f4b635a67f7f0cb05a1842de33e897a62bb64 /extcap.c | |
parent | c64762d33c3a9cbc4af4040284534b440d12b210 (diff) | |
download | wireshark-26bf66f423489fa3128d406c949954be5c39455c.tar.gz wireshark-26bf66f423489fa3128d406c949954be5c39455c.tar.bz2 wireshark-26bf66f423489fa3128d406c949954be5c39455c.zip |
extcap: plug more memory leaks
Fix leak of the preference key name which happen for every new extcap
argument. Fix leak of extcap arguments and the interface names in
extcap_register_preferences.
Change-Id: Idd68f924baa000303043cb98b32b23ce34fddb64
Reviewed-on: https://code.wireshark.org/review/17637
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
Diffstat (limited to 'extcap.c')
-rw-r--r-- | extcap.c | 38 |
1 files changed, 23 insertions, 15 deletions
@@ -455,10 +455,19 @@ append_extcap_interface_list(GList *list, char **err_str) { return list; } -void extcap_register_preferences(void) +static void +extcap_register_preferences_callback(gpointer key, gpointer value _U_, gpointer user_data _U_) { - GList * interfaces = NULL; + GList *arguments; + + arguments = extcap_get_if_configuration((gchar *)key); + /* Memory for prefs are external to an interface, they are part of + * extcap core, so the parsed arguments can be freed. */ + extcap_free_if_configuration(arguments, TRUE); +} +void extcap_register_preferences(void) +{ module_t * dev_module = prefs_find_module("extcap"); if ( !dev_module ) @@ -467,13 +476,7 @@ void extcap_register_preferences(void) if ( ! ifaces || g_hash_table_size(ifaces) == 0 ) extcap_reload_interface_list(NULL, NULL); - interfaces = g_hash_table_get_keys(ifaces); - - while ( interfaces ) { - extcap_get_if_configuration((gchar *)interfaces->data); - - interfaces = g_list_next(interfaces); - } + g_hash_table_foreach(ifaces, extcap_register_preferences_callback, NULL); } /** @@ -499,13 +502,15 @@ void extcap_pref_store(extcap_arg * arg, const char * newval) /** * Obtains a pointer which can store a value for the given preference name. + * The preference name that can be passed to the prefs API is stored into + * 'prefs_name'. * * Extcap interfaces (and their preferences) are dynamic, they can be created * and destroyed at will. Thus their data structures are insufficient to pass to * the preferences APIs which require pointers which are valid until the * preferences are removed (at exit). */ -static gchar ** extcap_prefs_dynamic_valptr(const char *name) +static gchar ** extcap_prefs_dynamic_valptr(const char *name, char **pref_name) { gchar **valp; if (!extcap_prefs_dynamic_vals) { @@ -513,11 +518,12 @@ static gchar ** extcap_prefs_dynamic_valptr(const char *name) extcap_prefs_dynamic_vals = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); } - valp = (gchar **)g_hash_table_lookup(extcap_prefs_dynamic_vals, name); - if (!valp) { + if (!g_hash_table_lookup_extended(extcap_prefs_dynamic_vals, name, + (gpointer *)pref_name, (gpointer *)&valp)) { /* New dynamic pref, allocate, initialize and store. */ valp = g_new0(gchar *, 1); - g_hash_table_insert(extcap_prefs_dynamic_vals, g_strdup(name), valp); + *pref_name = g_strdup(name); + g_hash_table_insert(extcap_prefs_dynamic_vals, *pref_name, valp); } return valp; } @@ -599,13 +605,15 @@ static gboolean search_cb(const gchar *extcap _U_, const gchar *ifname _U_, gcha gchar * pref_ifname = g_strconcat(ifname_lowercase, ".", pref_name, NULL); if ( ( pref = prefs_find_preference(dev_module, pref_ifname) ) == NULL ) { - arg->pref_valptr = extcap_prefs_dynamic_valptr(pref_ifname); + char *pref_name_for_prefs; + + arg->pref_valptr = extcap_prefs_dynamic_valptr(pref_ifname, &pref_name_for_prefs); /* Set an initial value if any (the string will be copied at registration) */ if (arg->default_complex) { *arg->pref_valptr = arg->default_complex->_val; } - prefs_register_string_preference(dev_module, g_strdup(pref_ifname), + prefs_register_string_preference(dev_module, pref_name_for_prefs, arg->display, arg->display, (const char **)arg->pref_valptr); } else { /* Been here before, restore stored value */ |