From 57f9ecb71cb043a315fa2d6a5f252cadf57c3980 Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Sun, 18 Oct 2009 13:00:10 +0200 Subject: Dynamic memory allocation for string replace functions This will fix all outstanding multithreading issues, coming from statically allocated memory, common for all threads. The algorithms have been further extended to allow input of any size. --- src/gallery-utils.c | 53 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 14 deletions(-) (limited to 'src/gallery-utils.c') diff --git a/src/gallery-utils.c b/src/gallery-utils.c index 0c24886..0f6ab71 100644 --- a/src/gallery-utils.c +++ b/src/gallery-utils.c @@ -28,6 +28,9 @@ #include "gallery-utils.h" + +#define STRING_ALLOC_SIZE 4096 + /* * str_replace: replace substring 'search' with a 'replace' string * - multiple occurrences of the string are replaced @@ -36,31 +39,41 @@ void str_replace (gchar **dst, const gchar *search, const gchar *replace) { - #define REPLACE_MAX_LENGTH 32768 - static gchar d[REPLACE_MAX_LENGTH]; + gchar *d; gchar *src; gchar *found; int i; + int alloc_size; + int used; - /* TODO: add range checking */ - if (strstr (*dst, search) == NULL || strlen (*dst) == 0 || strlen (search) == 0) + if (! dst || ! search || strlen (*dst) == 0 || strlen (search) == 0 || strstr (*dst, search) == NULL) return; + /* let's suppose just one occurrence of replace, realloc if needed */ + used = strlen (*dst) + 1; + alloc_size = (((used + strlen (replace)) / STRING_ALLOC_SIZE) + 1) * STRING_ALLOC_SIZE; + d = g_malloc (alloc_size); + i = 0; src = *dst; while (strstr (src, search)) { found = strstr (src, search); + used += strlen (replace) - strlen (search); + if (used > alloc_size) { + alloc_size = ((used / STRING_ALLOC_SIZE) + 1) * STRING_ALLOC_SIZE; + d = g_realloc (d, alloc_size); + } /* copy the data between search string */ if (found > src) { - memcpy (&d[i], src, found - src); + memcpy (d + i, src, found - src); i += found - src; } /* copy replace string instead */ if (strlen (replace) > 0) { - memcpy (&d[i], replace, strlen (replace)); + memcpy (d + i, replace, strlen (replace)); i += strlen (replace); } src = found + strlen (search); @@ -68,14 +81,15 @@ str_replace (gchar **dst, const gchar *search, const gchar *replace) /* copy the rest */ if (src) { - memcpy (&d[i], src, strlen (src)); + memcpy (d + i, src, strlen (src)); i += strlen (src); } d[i] = 0x0; /* return fixed string */ g_free (*dst); - *dst = g_strdup (&d[0]); + *dst = g_strdup (d); + g_free (d); } @@ -170,24 +184,29 @@ make_string (const gchar *substr, int count) void fix_entities (gchar **str) { - static gchar d[REPLACE_MAX_LENGTH]; + gchar *d; gchar *src; gchar *found; gchar *scan; int i; + int alloc_size; + int used; - /* TODO: add range checking */ if (! *str || strstr (*str, "&") == NULL) return; i = 0; src = *str; + used = strlen (src) + 1; + alloc_size = ((used / STRING_ALLOC_SIZE) + 1) * STRING_ALLOC_SIZE; + d = g_malloc (alloc_size); + while (strstr (src, "&")) { found = strstr (src, "&"); /* copy the data between search string */ - memcpy (&d[i], src, found - src + 1); + memcpy (d + i, src, found - src + 1); i += found - src + 1; /* scroll to next whitespace */ @@ -204,7 +223,12 @@ fix_entities (gchar **str) } else { /* replace with & */ - memcpy (&d[i], "amp;", 4); + used += 4; + if (used > alloc_size) { + alloc_size = ((used / STRING_ALLOC_SIZE) + 1) * STRING_ALLOC_SIZE; + d = g_realloc (d, alloc_size); + } + memcpy (d + i, "amp;", 4); i += 4; } src = found + 1; @@ -212,14 +236,15 @@ fix_entities (gchar **str) /* copy the rest */ if (src) { - memcpy (&d[i], src, strlen (src)); + memcpy (d + i, src, strlen (src)); i += strlen (src); } d[i] = 0x0; /* return fixed string */ g_free (*str); - *str = g_strdup (&d[0]); + *str = g_strdup (d); + g_free (d); } -- cgit v1.2.3