diff options
author | Joseph Hunkeler <jhunkeler@gmail.com> | 2024-12-06 08:21:58 -0500 |
---|---|---|
committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2024-12-06 08:21:58 -0500 |
commit | 2a15ece791252c07ddf2fe9868709bd80eecf489 (patch) | |
tree | f81dd301f9a5861e7c7ae33a1239d5a364153696 | |
parent | 5796ce9338c7fe2aa8a26766ff9e01448d785c99 (diff) | |
download | stasis-2a15ece791252c07ddf2fe9868709bd80eecf489.tar.gz |
Fix segfault in join_ex
* Calculate the number of function arguments with va_copy()
* Remove realloc() usage. No point.
-rw-r--r-- | src/lib/core/str.c | 32 |
1 files changed, 15 insertions, 17 deletions
diff --git a/src/lib/core/str.c b/src/lib/core/str.c index 45fb60a..d774e72 100644 --- a/src/lib/core/str.c +++ b/src/lib/core/str.c @@ -162,7 +162,7 @@ char *join(char **arr, const char *separator) { } char *join_ex(char *separator, ...) { - va_list ap; // Variadic argument list + va_list ap = {0}; // Variadic argument list size_t separator_len = 0; // Length of separator string size_t size = 0; // Length of output string size_t argc = 0; // Number of arguments ^ "..." @@ -174,13 +174,6 @@ char *join_ex(char *separator, ...) { return NULL; } - // Initialize array - argv = calloc(argc + 1, sizeof(char **)); - if (argv == NULL) { - perror("join_ex calloc failed"); - return NULL; - } - // Get length of the separator separator_len = strlen(separator); @@ -192,16 +185,21 @@ char *join_ex(char *separator, ...) { // 5. Append `current` string to `argv` array // 6. Update argument counter `argc` va_start(ap, separator); - for(argc = 0; (current = va_arg(ap, char *)) != NULL; argc++) { - char **tmp = realloc(argv, (argc + 1) * sizeof(char *)); - if (tmp == NULL) { - perror("join_ex realloc failed"); - GENERIC_ARRAY_FREE(argv); - return NULL; - } - argv = tmp; + va_list ap_tmp = {0}; + va_copy(ap_tmp, ap); + for(argc = 0; (current = va_arg(ap_tmp, char *)) != NULL; argc++) {} + va_end(ap_tmp); + + // Initialize array + argv = calloc(argc + 1, sizeof(char **)); + if (argv == NULL) { + perror("join_ex calloc failed"); + return NULL; + } + + for(size_t i = 0; i < argc && (current = va_arg(ap, char *)); i++) { size += strlen(current) + separator_len; - argv[argc] = strdup(current); + argv[i] = strdup(current); } va_end(ap); |