From 0ef7d92782cd8b3781174368280a9be67fdf190d Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Fri, 14 Nov 2008 14:15:32 +0000 Subject: [PATCH] Fix bug with utils_string_replace_all(). Make utils_str_replace() call utils_string_replace_all() internally (for better memory management and allowing replacements to match search string). git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@3226 ea778897-0a13-0410-b9d1-a72fbfd435f5 --- ChangeLog | 5 +++++ src/editor.c | 5 ++--- src/utils.c | 51 +++++++++++++-------------------------------------- 3 files changed, 20 insertions(+), 41 deletions(-) diff --git a/ChangeLog b/ChangeLog index 51078635..8e4f23f6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,11 @@ Prompt the user for whether to move the configuration directory or just quit instead. This is useful if the user is already running an older binary of Geany and the second instance is newer. + * src/utils.c, src/editor.c: + Fix bug with utils_string_replace_all(). + Make utils_str_replace() call utils_string_replace_all() internally + (for better memory management and allowing replacements to match + search string). 2008-11-13 Enrico Tröger diff --git a/src/editor.c b/src/editor.c index 1eda5459..86335775 100644 --- a/src/editor.c +++ b/src/editor.c @@ -1813,9 +1813,8 @@ static gboolean snippets_complete_constructs(GeanyEditor *editor, gint pos, cons pattern = snippets_global_pattern; } - /* replace line breaks and whitespaces */ - pattern = utils_str_replace(pattern, "\n", "%newline%"); /* to avoid endless replacing of \n */ - pattern = utils_str_replace(pattern, "%newline%", lindent); + /* add line indentation */ + pattern = utils_str_replace(pattern, "\n", lindent); /* replace any %template% wildcards */ pattern = snippets_replace_wildcards(editor, pattern); diff --git a/src/utils.c b/src/utils.c index db6e7de6..117a5442 100644 --- a/src/utils.c +++ b/src/utils.c @@ -497,45 +497,19 @@ gint utils_is_file_writeable(const gchar *locale_filename) /* Replaces all occurrences of needle in haystack with replacement. - * New code should use utils_string_replace_all() instead. - * All strings have to be NULL-terminated and needle and replacement have to be different, - * e.g. needle "%" and replacement "%%" causes an endless loop */ + * Warning: haystack will be freed. + * New code should use utils_string_replace_all() instead (freeing arguments + * is unusual behaviour). + * All strings have to be NULL-terminated. + * See utils_string_replace_all() for details. */ gchar *utils_str_replace(gchar *haystack, const gchar *needle, const gchar *replacement) { - gint i; - gchar *start; - gint lt_pos; - gchar *result; - GString *str; + GString *str = g_string_new(haystack); - if (haystack == NULL) - return NULL; - - if (needle == NULL || replacement == NULL) - return haystack; - - if (utils_str_equal(needle, replacement)) - return haystack; - - start = strstr(haystack, needle); - lt_pos = utils_strpos(haystack, needle); - - if (start == NULL || lt_pos == -1) - return haystack; - - /* substitute by copying */ - str = g_string_sized_new(strlen(haystack)); - for (i = 0; i < lt_pos; i++) - { - g_string_append_c(str, haystack[i]); - } - g_string_append(str, replacement); - g_string_append(str, haystack + lt_pos + strlen(needle)); - - result = str->str; g_free(haystack); - g_string_free(str, FALSE); - return utils_str_replace(result, needle, replacement); + utils_string_replace_all(str, needle, replacement); + + return g_string_free(str, FALSE); } @@ -1377,13 +1351,14 @@ gboolean utils_string_replace_all(GString *haystack, const gchar *needle, const pos = match - haystack->str; g_string_erase(haystack, pos, strlen(needle)); - /* next search is after removed matching text */ - stack = match; + /* make next search after removed matching text. + * (we have to be careful to only use haystack->str as its address may change) */ + stack = haystack->str + pos; if (replace) { g_string_insert(haystack, pos, replace); - stack += strlen(replace); /* don't replace replacements */ + stack = haystack->str + pos + strlen(replace); /* skip past replacement */ } } }