diff --git a/src/string.c b/src/string.c index 1d2a3bf..4f21fad 100644 --- a/src/string.c +++ b/src/string.c @@ -55,21 +55,45 @@ char* strnstr(const char* haystack, const char* needle, size_t s) char* strrepl(char* source, char* find, char* repl) { - size_t repl_len = strlen(repl); + const size_t find_len = strlen(find); + const size_t repl_len = strlen(repl); char* result = NULL; - char* n; - char* needle = source; + char* curr; + size_t is_last = 0; + char* last = source; + size_t str_size = 0; + size_t last_str_size; do { - n = strstr(needle, find); - if (!n) break; - result = realloc(result, n - source + repl_len + 1); - result[n - source + repl_len] = '\0'; - // Copy initial string up to here - strncpy(result, find, n - source - 1); + if (*last == '\0') break; + curr = strstr(last, find); + if (last == source && !curr) break; + // Move to end + else if (!curr) + { + curr = last + strlen(last); + is_last = 1; + } - } while (n); + // Increase to distance + last_str_size = str_size; + str_size += curr - last; + + // Create and copy + result = realloc(result, str_size + (!is_last ? repl_len : 0) + 1); + strncpy(result + last_str_size, last, curr - last); + if (!is_last) + { + strncpy(result + str_size, repl, repl_len); + + // Bump past replace size and null term + str_size += repl_len; + } + result[str_size] = '\0'; + // If is_last is true, this value doesn't matter + last = curr + find_len; + } while (curr && !is_last); // Return source string if no replacements return result ? result : source; diff --git a/test/Makefile b/test/Makefile index 17c96e3..d7b0f06 100644 --- a/test/Makefile +++ b/test/Makefile @@ -4,7 +4,7 @@ MASTODONT = $(MASTODONT_DIR)libmastodont.a CFLAGS += -g -Wall -I ../$(MASTODONT_DIR)include/ -Wno-unused-variable -Wno-discarded-qualifiers -I/usr/include/ $(shell pkg-config --cflags libcurl libcjson libpcre) LDFLAGS = -L./../$(MASTODONT_DIR) -lmastodont $(shell pkg-config --libs libcjson libcurl libpcre) -lfcgi TARGET = tests -SRC = unit/main.c ../src/mime.c +SRC = unit/main.c ../src/mime.c ../src/string.c OBJ = $(patsubst %.c,%.o,$(SRC)) all: $(TARGET) diff --git a/test/test.h b/test/test.h index 89811e2..06aed3f 100644 --- a/test/test.h +++ b/test/test.h @@ -31,10 +31,10 @@ int iterate_tests(struct test* tests, size_t tests_len) for (size_t i = 0; i < tests_len; ++i) { - printf("[ Test ] %04ld %s\n", i, tests->test_name); - status = tests->callback(); - printf("[ Test \"%s\" %s! ]\n", tests->test_name, !status ? "passed" : "failed"); - if (!status) + printf("[ Test ] %04ld %s\n", i, tests[i].test_name); + status = tests[i].callback(); + printf("[ Test \"%s\" %s! ]\n", tests[i].test_name, !status ? "passed" : "failed"); + if (status) return 1; } diff --git a/test/unit/mime_multipart.c b/test/unit/mime_multipart.c index c7530c7..99ba7c5 100644 --- a/test/unit/mime_multipart.c +++ b/test/unit/mime_multipart.c @@ -42,14 +42,14 @@ void form_check(void) // Copy and test strcpy(multipart, MULTIPART_TEST); - pos = read_form_data(BOUNDARY_RES_T, multipart, &info); + pos = read_form_data(BOUNDARY_RES_T, multipart, &info, sizeof(MULTIPART_TEST)-1); assert(pos != NULL); assert(strcmp(info.name, "text") == 0); assert(strcmp(info.value, "text default") == 0); // test next value - pos = read_form_data(BOUNDARY_RES_T, pos, &info); + pos = read_form_data(BOUNDARY_RES_T, pos, &info, sizeof(MULTIPART_TEST) - (pos - multipart)); assert(pos != NULL); assert(strcmp(info.name, "file1") == 0); diff --git a/test/unit/string_test.c b/test/unit/string_test.c index 2f570ec..c76ea9f 100644 --- a/test/unit/string_test.c +++ b/test/unit/string_test.c @@ -1,6 +1,19 @@ +#include +#include "../../src/string.h" int string_replace_test(void) { - strrepl + char* res1 = strrepl("hello world", "wo", "swi"); + assert(strcmp(res1, "hello swirld") == 0); + char* res2 = strrepl("hello world itswo the world wo", "wo", "swi"); + assert(strcmp(res2, "hello swirld itsswi the swirld swi") == 0); + char* res3 = strrepl(">implying\nhuh? <><", ">", ">"); + assert(strcmp(res3, ">implying\nhuh? <><") == 0); + char* res4 = strrepl(">lol >hi", ">", ">>>"); + assert(strcmp(res4, ">>>lol >>>hi") == 0); + free(res1); + free(res2); + free(res3); + free(res4); return 0; }