diff --git a/ChangeLog b/ChangeLog index 1e2eb0db5..198cc8453 100644 --- a/ChangeLog +++ b/ChangeLog @@ -13,6 +13,10 @@ src/symbols.h: Move symbol list popup menu code to symbols.c. Add symbols_init(). + * src/templates.c, src/build.c, src/utils.c, src/utils.h, + src/project.c, src/search.c, src/editor.c: + Make utils_free_pointers() take an arg_count argument to prevent + memory leaks. 2008-11-16 Enrico Tröger diff --git a/src/build.c b/src/build.c index 08155b2f5..2bb29750a 100644 --- a/src/build.c +++ b/src/build.c @@ -178,7 +178,7 @@ static GPid build_view_tex_file(GeanyDocument *doc, gint mode) if (g_stat(locale_filename, &st) != 0) { ui_set_statusbar(TRUE, _("Failed to view %s (make sure it is already compiled)"), view_file); - utils_free_pointers(executable, view_file, locale_filename, NULL); + utils_free_pointers(3, executable, view_file, locale_filename, NULL); return (GPid) 1; } @@ -213,7 +213,7 @@ static GPid build_view_tex_file(GeanyDocument *doc, gint mode) _("Could not find terminal \"%s\" " "(check path for Terminal tool setting in Preferences)"), tool_prefs.term_cmd); - utils_free_pointers(executable, view_file, locale_filename, cmd_string, locale_cmd_string, + utils_free_pointers(6, executable, view_file, locale_filename, cmd_string, locale_cmd_string, locale_term_cmd, NULL); g_strfreev(term_argv); return (GPid) 1; @@ -227,7 +227,7 @@ static GPid build_view_tex_file(GeanyDocument *doc, gint mode) { ui_set_statusbar(TRUE, _("Failed to execute \"%s\" (start-script could not be created)"), executable); - utils_free_pointers(executable, view_file, locale_filename, cmd_string, locale_cmd_string, + utils_free_pointers(7, executable, view_file, locale_filename, cmd_string, locale_cmd_string, locale_term_cmd, working_dir, NULL); g_strfreev(term_argv); return (GPid) 1; @@ -264,7 +264,7 @@ static GPid build_view_tex_file(GeanyDocument *doc, gint mode) geany_debug("g_spawn_async() failed: %s", error->message); ui_set_statusbar(TRUE, _("Process failed (%s)"), error->message); - utils_free_pointers(executable, view_file, locale_filename, cmd_string, locale_cmd_string, + utils_free_pointers(6, executable, view_file, locale_filename, cmd_string, locale_cmd_string, locale_term_cmd, NULL); g_strfreev(argv); g_strfreev(term_argv); @@ -280,7 +280,7 @@ static GPid build_view_tex_file(GeanyDocument *doc, gint mode) build_menu_update(doc); } - utils_free_pointers(executable, view_file, locale_filename, cmd_string, locale_cmd_string, + utils_free_pointers(6, executable, view_file, locale_filename, cmd_string, locale_cmd_string, locale_term_cmd, NULL); g_strfreev(argv); g_strfreev(term_argv); @@ -641,7 +641,7 @@ static gchar *prepare_run_script(GeanyDocument *doc, gchar **vte_cmd_nonscript) gchar *utf8_working_dir = utils_get_utf8_from_locale(working_dir); ui_set_statusbar(TRUE, _("Failed to change the working directory to \"%s\""), utf8_working_dir); - utils_free_pointers(utf8_working_dir, working_dir, executable, locale_filename, NULL); + utils_free_pointers(4, utf8_working_dir, working_dir, executable, locale_filename, NULL); return NULL; } @@ -660,7 +660,7 @@ static gchar *prepare_run_script(GeanyDocument *doc, gchar **vte_cmd_nonscript) if (vte_cmd_nonscript != NULL) *vte_cmd_nonscript = cmd; - utils_free_pointers(executable, locale_filename, NULL); + utils_free_pointers(2, executable, locale_filename, NULL); return working_dir; } else @@ -682,7 +682,7 @@ static gchar *prepare_run_script(GeanyDocument *doc, gchar **vte_cmd_nonscript) g_free(utf8_cmd); } - utils_free_pointers(tmp, cmd, executable, locale_filename, NULL); + utils_free_pointers(4, tmp, cmd, executable, locale_filename, NULL); if (result) return working_dir; diff --git a/src/editor.c b/src/editor.c index 8b538590a..f56de339a 100644 --- a/src/editor.c +++ b/src/editor.c @@ -1686,7 +1686,7 @@ static gchar *snippets_replace_wildcards(GeanyEditor *editor, gchar *text) text = templates_replace_all(text, year, date, datetime); text = utils_str_replace(text, "{filename}", basename); - utils_free_pointers(year, date, datetime, basename, NULL); + utils_free_pointers(4, year, date, datetime, basename, NULL); return text; } @@ -1799,7 +1799,7 @@ static gboolean snippets_complete_constructs(GeanyEditor *editor, gint pos, cons pattern = snippets_find_completion_by_name(filetypes[ft_id]->name, str); if (pattern == NULL || pattern[0] == '\0') { - utils_free_pointers(str, pattern, NULL); /* free pattern in case it is "" */ + utils_free_pointers(2, str, pattern, NULL); /* free pattern in case it is "" */ return FALSE; } @@ -1839,7 +1839,7 @@ static gboolean snippets_complete_constructs(GeanyEditor *editor, gint pos, cons editor_insert_text_block(editor, pattern, pos, cur_index, -1); sci_scroll_caret(sci); - utils_free_pointers(pattern, str, NULL); + utils_free_pointers(2, pattern, str, NULL); return TRUE; } diff --git a/src/project.c b/src/project.c index c22a61ad6..901848c2f 100644 --- a/src/project.c +++ b/src/project.c @@ -627,7 +627,7 @@ static gboolean update_config(const PropertyDialogElements *e) SHOW_ERR1(_("Project base directory could not be created (%s)."), g_strerror(err_code)); gtk_widget_grab_focus(e->base_path); - utils_free_pointers(locale_path, locale_filename, NULL); + utils_free_pointers(2, locale_path, locale_filename, NULL); return FALSE; } } diff --git a/src/search.c b/src/search.c index f1e3f2f62..4b304ead0 100644 --- a/src/search.c +++ b/src/search.c @@ -1321,7 +1321,7 @@ search_find_in_files(const gchar *utf8_search_text, const gchar *dir, const gcha tool_prefs.grep_cmd, opts, utf8_search_text, dir); utf8_str = utils_get_utf8_from_locale(str); msgwin_msg_add(COLOR_BLUE, -1, NULL, utf8_str); - utils_free_pointers(str, utf8_str, NULL); + utils_free_pointers(2, str, utf8_str, NULL); ret = TRUE; } g_strfreev(argv); diff --git a/src/templates.c b/src/templates.c index f2dee61cf..53aa4fcd0 100644 --- a/src/templates.c +++ b/src/templates.c @@ -390,7 +390,7 @@ static gchar *get_template_from_file(const gchar *locale_fname, const gchar *doc utils_string_replace_all(&template, "{filename}", doc_filename); utils_string_replace_all(&template, "{fileheader}", file_header); - utils_free_pointers(year, date, datetime, file_header, NULL); + utils_free_pointers(4, year, date, datetime, file_header, NULL); } return template.str; } diff --git a/src/utils.c b/src/utils.c index 0232633b7..cbcdd8a36 100644 --- a/src/utils.c +++ b/src/utils.c @@ -505,10 +505,10 @@ gint utils_is_file_writeable(const gchar *locale_filename) gchar *utils_str_replace(gchar *haystack, const gchar *needle, const gchar *replacement) { GString *str; - + if (haystack == NULL) return NULL; - + str = g_string_new(haystack); g_free(haystack); @@ -1101,24 +1101,24 @@ gchar *utils_get_utf8_from_locale(const gchar *locale_text) } -/* Frees all passed pointers if they are *ALL* non-NULL. - * Do not use if any pointers may be NULL. - * The first argument is nothing special, it will also be freed. - * The list must be ended with NULL. */ -void utils_free_pointers(gpointer first, ...) +/* Pass pointers to free after arg_count. + * The last argument must be NULL as an extra check that arg_count is correct. */ +void utils_free_pointers(gsize arg_count, ...) { va_list a; - gpointer sa; + gsize i; + gpointer ptr; - for (va_start(a, first); (sa = va_arg(a, gpointer), sa!=NULL);) - { - if (sa != NULL) - g_free(sa); + va_start(a, arg_count); + for (i = 0; i < arg_count; i++) + { + ptr = va_arg(a, gpointer); + g_free(ptr); } + ptr = va_arg(a, gpointer); + if (ptr) + g_warning("Wrong arg_count!"); va_end(a); - - if (first != NULL) - g_free(first); } diff --git a/src/utils.h b/src/utils.h index d33af164e..2eb92c44d 100644 --- a/src/utils.h +++ b/src/utils.h @@ -118,7 +118,7 @@ gchar *utils_get_locale_from_utf8(const gchar *utf8_text); gchar *utils_get_utf8_from_locale(const gchar *locale_text); -void utils_free_pointers(gpointer first, ...) G_GNUC_NULL_TERMINATED; +void utils_free_pointers(gsize arg_count, ...) G_GNUC_NULL_TERMINATED; gchar **utils_strv_new(const gchar *first, ...) G_GNUC_NULL_TERMINATED;