diff --git a/include/strutils.h b/include/strutils.h index 7969a84d0..a62f72493 100644 --- a/include/strutils.h +++ b/include/strutils.h @@ -315,16 +315,20 @@ static inline size_t ltrim_whitespace(unsigned char *str) /* Removes left-hand, right-hand and repeating whitespaces. */ -static inline size_t normalize_whitespace(unsigned char *str) +static inline size_t __normalize_whitespace( + const unsigned char *src, + size_t sz, + unsigned char *dst, + size_t len) { - size_t i, x, sz = strlen((char *) str); + size_t i, x = 0; int nsp = 0, intext = 0; if (!sz) - return 0; + goto done; - for (i = 0, x = 0; i < sz; ) { - if (isspace(str[i])) + for (i = 0, x = 0; i < sz && x < len - 1; ) { + if (isspace(src[i])) nsp++; else nsp = 0, intext = 1; @@ -332,14 +336,21 @@ static inline size_t normalize_whitespace(unsigned char *str) if (nsp > 1 || (nsp && !intext)) i++; else - str[x++] = str[i++]; + dst[x++] = src[i++]; } - if (nsp) /* tailing space */ + if (nsp && x > 0) /* tailing space */ x--; - str[x] = '\0'; +done: + dst[x] = '\0'; return x; } +static inline size_t normalize_whitespace(unsigned char *str) +{ + size_t sz = strlen((char *) str); + return __normalize_whitespace(str, sz, str, sz + 1); +} + static inline void strrep(char *s, int find, int replace) { while (s && *s && (s = strchr(s, find)) != NULL) diff --git a/lib/strutils.c b/lib/strutils.c index 5b5e686aa..68b664748 100644 --- a/lib/strutils.c +++ b/lib/strutils.c @@ -1175,17 +1175,26 @@ static int test_strutils_cmp_paths(int argc, char *argv[]) static int test_strutils_normalize(int argc, char *argv[]) { - unsigned char *str; - size_t sz; + unsigned char *src, *dst; + size_t sz, len; if (argc < 2) return EXIT_FAILURE; - str = (unsigned char *) strdup(argv[1]); - sz = normalize_whitespace(str); + src = (unsigned char *) strdup(argv[1]); + len = strlen((char *) src); + dst = malloc(len + 1); - printf("'%s' --> '%s' [sz=%zu]\n", argv[1], str, sz); - free(str); + /* two buffers */ + sz = __normalize_whitespace(src, len, dst, len + 1); + printf("1: '%s' --> '%s' [sz=%zu]\n", src, dst, sz); + + /* one buffer */ + sz = normalize_whitespace(src); + printf("2: '%s' --> '%s' [sz=%zu]\n", argv[1], src, sz); + + free(src); + free(dst); return EXIT_SUCCESS; }