From d86ca1176dea94312d7e0ec72e53e35c2c83309a Mon Sep 17 00:00:00 2001 From: ejurgensen Date: Tue, 11 Feb 2020 14:12:04 +0100 Subject: [PATCH] [misc] Add an in-place string replacement function --- src/misc.c | 47 ++++++++++++++++++++++++++++++++++++++++++++--- src/misc.h | 2 ++ 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/src/misc.c b/src/misc.c index 36427404..3a91b44e 100644 --- a/src/misc.c +++ b/src/misc.c @@ -380,6 +380,49 @@ safe_snprintf_cat(char *dst, size_t n, const char *fmt, ...) return -1; } +int +safe_snreplace(char *s, size_t sz, const char *pattern, const char *replacement) +{ + char *ptr; + char *src; + char *dst; + size_t num; + + if (!s) + return -1; + + if (!pattern || !replacement) + return 0; + + size_t p_len = strlen(pattern); + size_t r_len = strlen(replacement); + size_t s_len = strlen(s) + 1; // Incl terminator + + ptr = s; + while ((ptr = strstr(ptr, pattern))) + { + // We will move the part of the string after the pattern from src to dst + src = ptr + p_len; + dst = ptr + r_len; + + num = s_len - (src - s); // Number of bytes w/terminator we need to move + if (dst + num > s + sz) + return -1; // Not enough room + + // Shift everything after the pattern to the right, use memmove since + // there might be an overlap + memmove(dst, src, num); + + // Write replacement, no null terminater + memcpy(ptr, replacement, r_len); + + // Advance ptr to avoid infinite looping + ptr = dst; + } + + return 0; +} + /* Key/value functions */ struct keyval * @@ -387,7 +430,7 @@ keyval_alloc(void) { struct keyval *kv; - kv = (struct keyval *)malloc(sizeof(struct keyval)); + kv = calloc(1, sizeof(struct keyval)); if (!kv) { DPRINTF(E_LOG, L_MISC, "Out of memory for keyval alloc\n"); @@ -395,8 +438,6 @@ keyval_alloc(void) return NULL; } - memset(kv, 0, sizeof(struct keyval)); - return kv; } diff --git a/src/misc.h b/src/misc.h index 06ee8bd0..ce1af74a 100644 --- a/src/misc.h +++ b/src/misc.h @@ -87,6 +87,8 @@ safe_asprintf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); int safe_snprintf_cat(char *dst, size_t n, const char *fmt, ...) __attribute__ ((format (printf, 3, 4))); +int +safe_snreplace(char *s, size_t sz, const char *pattern, const char *replacement); /* Key/value functions */ struct keyval *