diff --git a/extcap.c b/extcap.c index 948880de34..d0aef953c9 100644 --- a/extcap.c +++ b/extcap.c @@ -119,11 +119,14 @@ extcap_if_executable(const gchar *ifname) return interface != NULL ? interface->extcap_path : NULL; } -static void +static gboolean extcap_if_add(extcap_interface * interface) { - if (!g_hash_table_lookup(ifaces, interface->call)) - g_hash_table_insert(ifaces, g_strdup(interface->call), interface); + if (g_hash_table_lookup(ifaces, interface->call)) + return FALSE; + + g_hash_table_insert(ifaces, g_strdup(interface->call), interface); + return TRUE; } static void @@ -202,6 +205,12 @@ static void extcap_free_dlt(gpointer d, gpointer user_data _U_) { g_free(((extcap_dlt *)d)->name); g_free(((extcap_dlt *)d)->display); + g_free(d); +} + +static void extcap_free_dlts(GList * dlts) { + g_list_foreach(dlts, extcap_free_dlt, NULL); + g_list_free(dlts); } static gboolean dlt_cb(const gchar *extcap _U_, const gchar *ifname _U_, gchar *output, void *data, @@ -253,7 +262,7 @@ static gboolean dlt_cb(const gchar *extcap _U_, const gchar *ifname _U_, gchar * g_free(caps); } - g_list_foreach(temp, extcap_free_dlt, NULL); + extcap_free_dlts(temp); return FALSE; } @@ -293,12 +302,22 @@ static void extcap_free_interface(gpointer i) { g_free(interface->display); g_free(interface->version); g_free(interface->help); + g_free(interface->extcap_path); + g_free(interface); +} + +static void extcap_free_interfaces(GList * interfaces) { + if (interfaces == NULL) + return; + + g_list_foreach(interfaces, (GFunc)extcap_free_interface, NULL); + g_list_free(interfaces); } static gboolean interfaces_cb(const gchar *extcap, const gchar *ifname _U_, gchar *output, void *data, char **err_str _U_) { GList **il = (GList **) data; - GList *interfaces = NULL, *walker = NULL; + GList *interfaces = NULL, *walker = NULL, *tmp = NULL; extcap_interface *int_iter = NULL; if_info_t *if_info = NULL; @@ -308,6 +327,9 @@ static gboolean interfaces_cb(const gchar *extcap, const gchar *ifname _U_, gcha walker = interfaces; while (walker != NULL ) { + /* Whether the interface information needs to be preserved or not. */ + gboolean preserve_interface = FALSE; + int_iter = (extcap_interface *)walker->data; if ( int_iter->if_type == EXTCAP_SENTENCE_INTERFACE && extcap_if_exists(int_iter->call) ) { @@ -336,15 +358,23 @@ static gboolean interfaces_cb(const gchar *extcap, const gchar *ifname _U_, gcha } int_iter->extcap_path = g_strdup(extcap); - extcap_if_add(int_iter); + preserve_interface = extcap_if_add(int_iter); } /* Call for interfaces and tools alike. Multiple calls (because a tool has multiple * interfaces) are handled internally */ extcap_tool_add(extcap, int_iter); + tmp = walker; walker = g_list_next(walker); + + /* If interface was added to ifaces hash list then the hash list will free + * the resources. Remove the interface from interfaces list so it won't be + * freed when exiting this function */ + if (preserve_interface) + interfaces = g_list_delete_link(interfaces, tmp); } + extcap_free_interfaces(interfaces); return TRUE; } @@ -425,11 +455,6 @@ append_extcap_interface_list(GList *list, char **err_str) { return list; } -static void extcap_free_arg_elem(gpointer data, gpointer user_data _U_) { - extcap_free_arg((extcap_arg *) data); - g_free(data); -} - void extcap_register_preferences(void) { GList * interfaces = NULL; @@ -497,17 +522,18 @@ static gchar ** extcap_prefs_dynamic_valptr(const char *name) return valp; } -static void extcap_free_if_configuration(GList *list) +void extcap_free_if_configuration(GList *list, gboolean free_args) { GList *elem, *sl; for (elem = g_list_first(list); elem; elem = elem->next) { if (elem->data != NULL) { - /* g_list_free_full() only exists since 2.28. */ sl = g_list_first((GList *)elem->data); - g_list_foreach(sl, (GFunc)extcap_free_arg_elem, NULL); - g_list_free(sl); + if (free_args) + extcap_free_arg_list(sl); + else + g_list_free(sl); } } g_list_free(list); @@ -692,7 +718,7 @@ extcap_has_configuration(const char * ifname, gboolean is_required) { } walker = walker->next; } - extcap_free_if_configuration(arguments); + extcap_free_if_configuration(arguments, TRUE); return found; } @@ -988,7 +1014,7 @@ GPtrArray * extcap_prepare_arguments(interface_options interface_opts) } } - extcap_free_if_configuration(arglist); + extcap_free_if_configuration(arglist, TRUE); } else { diff --git a/extcap.h b/extcap.h index dd39247dd0..e427f45a6d 100644 --- a/extcap.h +++ b/extcap.h @@ -88,6 +88,15 @@ extcap_tools_list(void); GList * extcap_get_if_configuration(const char * ifname); +/** + * Frees the memory from extcap_get_if_configuration. + * @param list The list returned by extcap_get_if_configuration. + * @param free_args TRUE if all arguments in the list must be freed too or FALSE + * if the ownership of the arguments is taken by the caller. + */ +void +extcap_free_if_configuration(GList *list, gboolean free_args); + gboolean extcap_has_configuration(const char * ifname, gboolean is_required); diff --git a/extcap_parser.c b/extcap_parser.c index f9e2c856ea..0fd4c8f9ac 100644 --- a/extcap_parser.c +++ b/extcap_parser.c @@ -118,7 +118,6 @@ static extcap_token_sentence *extcap_tokenize_sentence(const gchar *s) { extcap_token_sentence *rs = g_new0(extcap_token_sentence, 1); rs->sentence = NULL; - rs->param_list = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free); /* Regex for catching just the allowed values for sentences */ if ( ( regex = g_regex_new ( "^[\\t| ]*(arg|value|interface|extcap|dlt)(?=[\\t| ]+\\{)", @@ -137,6 +136,8 @@ static extcap_token_sentence *extcap_tokenize_sentence(const gchar *s) { return NULL; } + rs->param_list = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free); + /* Capture the argument and the value of the list. This will ensure, * that regex patterns given to {validation=} are parsed correctly, * as long as }{ does not occur within the pattern */ @@ -150,7 +151,7 @@ static extcap_token_sentence *extcap_tokenize_sentence(const gchar *s) { if ( arg == NULL ) break; - param_value = g_strdup(g_match_info_fetch ( match_info, 2 )); + param_value = g_match_info_fetch ( match_info, 2 ); if (g_ascii_strcasecmp(arg, "number") == 0) { param_type = EXTCAP_PARAM_ARGNUM; @@ -197,6 +198,7 @@ static extcap_token_sentence *extcap_tokenize_sentence(const gchar *s) { g_hash_table_insert(rs->param_list, ENUM_KEY(param_type), param_value); g_match_info_next(match_info, &error); + g_free(arg); } g_match_info_free(match_info); g_regex_unref(regex); @@ -260,15 +262,12 @@ void extcap_free_arg(extcap_arg *a) { extcap_free_complex(a->default_complex); g_list_foreach(a->values, (GFunc) extcap_free_valuelist, NULL); -} - -static void extcap_free_arg_list_cb(gpointer listentry, gpointer data _U_) { - if (listentry != NULL) - extcap_free_arg((extcap_arg *) listentry); + g_list_free(a->values); + g_free(a); } void extcap_free_arg_list(GList *a) { - g_list_foreach(a, extcap_free_arg_list_cb, NULL); + g_list_foreach(a, (GFunc)extcap_free_arg, NULL); g_list_free(a); } @@ -279,12 +278,22 @@ static gint glist_find_numbered_arg(gconstpointer listelem, gconstpointer needle } static void extcap_free_tokenized_sentence(gpointer s, gpointer user_data _U_) { + extcap_token_sentence *t = (extcap_token_sentence *)s; - if (s == NULL) + if (t == NULL) return; - g_free(((extcap_token_sentence *)s)->sentence); - g_hash_table_destroy(((extcap_token_sentence *)s)->param_list); + g_free(t->sentence); + g_hash_table_destroy(t->param_list); + g_free(t); +} + +static void extcap_free_tokenized_sentences(GList *sentences) { + if (sentences == NULL) + return; + + g_list_foreach(sentences, extcap_free_tokenized_sentence, NULL); + g_list_free(sentences); } static extcap_arg *extcap_parse_arg_sentence(GList * args, extcap_token_sentence *s) { @@ -530,7 +539,7 @@ GList * extcap_parse_args(gchar *output) { walker = g_list_next(walker); } - g_list_foreach(temp, extcap_free_tokenized_sentence, NULL); + extcap_free_tokenized_sentences(temp); return result; } @@ -603,7 +612,7 @@ GList * extcap_parse_interfaces(gchar *output) { walker = g_list_next(walker); } - g_list_foreach(tokens, extcap_free_tokenized_sentence, NULL); + extcap_free_tokenized_sentences(tokens); return result; } @@ -681,7 +690,7 @@ GList * extcap_parse_dlts(gchar *output) { walker = g_list_next(walker); } - g_list_foreach(temp, extcap_free_tokenized_sentence, NULL); + extcap_free_tokenized_sentences(temp); return result; } diff --git a/extcap_spawn.c b/extcap_spawn.c index 484269370c..7a3984dd21 100644 --- a/extcap_spawn.c +++ b/extcap_spawn.c @@ -122,6 +122,7 @@ gboolean extcap_spawn_sync ( gchar * dirname, gchar * command, gint argc, gchar if (!CreatePipe(&child_stdout_rd, &child_stdout_wr, &sa, 0)) { + g_free(argv[0]); g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "Could not create stdout handle"); return FALSE; } @@ -130,6 +131,7 @@ gboolean extcap_spawn_sync ( gchar * dirname, gchar * command, gint argc, gchar { CloseHandle(child_stdout_rd); CloseHandle(child_stdout_wr); + g_free(argv[0]); g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "Could not create stderr handle"); return FALSE; } @@ -192,6 +194,7 @@ gboolean extcap_spawn_sync ( gchar * dirname, gchar * command, gint argc, gchar } g_free(local_output); + g_free(argv[0]); g_free(argv); return result; diff --git a/ui/qt/extcap_options_dialog.cpp b/ui/qt/extcap_options_dialog.cpp index 0c1e8bae9d..ae798e29d9 100644 --- a/ui/qt/extcap_options_dialog.cpp +++ b/ui/qt/extcap_options_dialog.cpp @@ -194,7 +194,7 @@ void ExtcapOptionsDialog::anyValueChanged() void ExtcapOptionsDialog::loadArguments() { - GList * arguments = NULL, * item = NULL; + GList * arguments = NULL, * walker = NULL, * item = NULL; ExtcapArgument * argument = NULL; if ( device_name.length() == 0 ) @@ -207,9 +207,10 @@ void ExtcapOptionsDialog::loadArguments() ExtcapArgumentList required; ExtcapArgumentList optional; - while ( arguments != NULL ) + walker = arguments; + while ( walker != NULL ) { - item = g_list_first((GList *)(arguments->data)); + item = g_list_first((GList *)(walker->data)); while ( item != NULL ) { argument = ExtcapArgument::create((extcap_arg *)(item->data)); @@ -223,7 +224,7 @@ void ExtcapOptionsDialog::loadArguments() } item = item->next; } - arguments = g_list_next(arguments); + walker = g_list_next(walker); } if ( required.length() > 0 ) @@ -231,6 +232,9 @@ void ExtcapOptionsDialog::loadArguments() if ( optional.length() > 0 ) extcapArguments << optional; + + /* argument items are now owned by ExtcapArgument. Only free the lists */ + extcap_free_if_configuration(arguments, FALSE); } void ExtcapOptionsDialog::updateWidgets()