X-Git-Url: https://git.octo.it/?p=collectd.git;a=blobdiff_plain;f=src%2Fdaemon%2Futils_subst.c;h=a016342540cf95332074bcb395a6564adc512316;hp=3e554973c7698dc54bd6d32c0d612e11270a1223;hb=7111bb6df7628edce3a8e538b386fbe27633a191;hpb=e0e307657d6b751d6beb5afb92c9359a6df7f5e8 diff --git a/src/daemon/utils_subst.c b/src/daemon/utils_subst.c index 3e554973..a0163425 100644 --- a/src/daemon/utils_subst.c +++ b/src/daemon/utils_subst.c @@ -29,122 +29,133 @@ */ #include "collectd.h" + #include "common.h" #include "utils_subst.h" -char *subst (char *buf, size_t buflen, const char *string, int off1, int off2, - const char *replacement) -{ - char *buf_ptr = buf; - size_t len = buflen; - - if ((NULL == buf) || (0 >= buflen) || (NULL == string) - || (0 > off1) || (0 > off2) || (off1 > off2) - || (NULL == replacement)) - return NULL; - - sstrncpy (buf_ptr, string, - ((size_t)off1 + 1 > buflen) ? buflen : (size_t)off1 + 1); - buf_ptr += off1; - len -= off1; - - if (0 >= len) - return buf; - - sstrncpy (buf_ptr, replacement, len); - buf_ptr += strlen (replacement); - len -= strlen (replacement); - - if (0 >= len) - return buf; - - sstrncpy (buf_ptr, string + off2, len); - return buf; +char *subst(char *buf, size_t buflen, const char *string, size_t off1, + size_t off2, const char *replacement) { + char *out = buf; + + char const *front; + char const *back; + size_t front_len; + size_t replacement_len; + size_t back_len; + + if ((NULL == buf) || (0 == buflen) || (NULL == string) || + (NULL == replacement)) + return NULL; + + size_t string_len = strlen(string); + if ((off1 > string_len) || (off2 > string_len) || (off1 > off2)) + return NULL; + + front = string; + back = string + off2; + front_len = off1; + replacement_len = strlen(replacement); + back_len = strlen(back); + + if (front_len >= buflen) { + front_len = buflen - 1; + replacement_len = 0; + back_len = 0; + } else if ((front_len + replacement_len) >= buflen) { + replacement_len = buflen - (front_len + 1); + back_len = 0; + } else if ((front_len + replacement_len + back_len) >= buflen) { + back_len = buflen - (front_len + replacement_len + 1); + } else { + buflen = front_len + replacement_len + back_len + 1; + } + assert((front_len + replacement_len + back_len) == (buflen - 1)); + + if (front_len != 0) { + sstrncpy(out, front, front_len + 1); + out += front_len; + } + + if (replacement_len != 0) { + sstrncpy(out, replacement, replacement_len + 1); + out += replacement_len; + } + + if (back_len != 0) { + sstrncpy(out, back, back_len + 1); + out += back_len; + } + + out[0] = 0; + return buf; } /* subst */ -char *asubst (const char *string, int off1, int off2, const char *replacement) -{ - char *buf; - int len; +char *asubst(const char *string, int off1, int off2, const char *replacement) { + char *buf; + int len; - char *ret; + char *ret; - if ((NULL == string) || (0 > off1) || (0 > off2) || (off1 > off2) - || (NULL ==replacement)) - return NULL; + if ((NULL == string) || (0 > off1) || (0 > off2) || (off1 > off2) || + (NULL == replacement)) + return NULL; - len = off1 + strlen (replacement) + strlen (string) - off2 + 1; + len = off1 + strlen(replacement) + strlen(string) - off2 + 1; - buf = (char *)malloc (len); - if (NULL == buf) - return NULL; + buf = malloc(len); + if (NULL == buf) + return NULL; - ret = subst (buf, len, string, off1, off2, replacement); - if (NULL == ret) - free (buf); - return ret; + ret = subst(buf, len, string, off1, off2, replacement); + if (NULL == ret) + free(buf); + return ret; } /* asubst */ -char *subst_string (char *buf, size_t buflen, const char *string, - const char *needle, const char *replacement) -{ - char *temp; - size_t needle_len; - size_t i; - - if ((buf == NULL) || (string == NULL) - || (needle == NULL) || (replacement == NULL)) - return (NULL); - - temp = (char *) malloc (buflen); - if (temp == NULL) - { - ERROR ("subst_string: malloc failed."); - return (NULL); - } - - needle_len = strlen (needle); - strncpy (buf, string, buflen); - - /* Limit the loop to prevent endless loops. */ - for (i = 0; i < buflen; i++) - { - char *begin_ptr; - size_t begin; - - /* Find `needle' in `buf'. */ - begin_ptr = strstr (buf, needle); - if (begin_ptr == NULL) - break; - - /* Calculate the start offset. */ - begin = begin_ptr - buf; - - /* Substitute the region using `subst'. The result is stored in - * `temp'. */ - begin_ptr = subst (temp, buflen, buf, - begin, begin + needle_len, - replacement); - if (begin_ptr == NULL) - { - WARNING ("subst_string: subst failed."); - break; - } - - /* Copy the new string in `temp' to `buf' for the next round. */ - strncpy (buf, temp, buflen); - } - - if (i >= buflen) - { - WARNING ("subst_string: Loop exited after %zu iterations: " - "string = %s; needle = %s; replacement = %s;", - i, string, needle, replacement); - } - - sfree (temp); - return (buf); +char *subst_string(char *buf, size_t buflen, const char *string, + const char *needle, const char *replacement) { + size_t needle_len; + size_t i; + + if ((buf == NULL) || (string == NULL) || (needle == NULL) || + (replacement == NULL)) + return NULL; + + needle_len = strlen(needle); + sstrncpy(buf, string, buflen); + + /* Limit the loop to prevent endless loops. */ + for (i = 0; i < buflen; i++) { + char temp[buflen]; + char *begin_ptr; + size_t begin; + + /* Find `needle' in `buf'. */ + begin_ptr = strstr(buf, needle); + if (begin_ptr == NULL) + break; + + /* Calculate the start offset. */ + begin = begin_ptr - buf; + + /* Substitute the region using `subst'. The result is stored in + * `temp'. */ + begin_ptr = + subst(temp, buflen, buf, begin, begin + needle_len, replacement); + if (begin_ptr == NULL) { + WARNING("subst_string: subst failed."); + break; + } + + /* Copy the new string in `temp' to `buf' for the next round. */ + strncpy(buf, temp, buflen); + } + + if (i >= buflen) { + WARNING("subst_string: Loop exited after %zu iterations: " + "string = %s; needle = %s; replacement = %s;", + i, string, needle, replacement); + } + + return buf; } /* char *subst_string */ - -/* vim: set sw=4 ts=4 tw=78 noexpandtab : */ -