From fbb45554ddd9c0e10c3acd9e7d79314b3cda9f07 Mon Sep 17 00:00:00 2001 From: Pascal Bauer Date: Thu, 26 Jun 2025 11:47:47 +0200 Subject: [PATCH 1/2] fix: Portability of vstrcatf and vstrf Specifiying the "va" parameter as reference to ensure reproducable behavior on arm and x86. Signed-off-by: Pascal Bauer --- common/include/villas/utils.hpp | 4 ++-- common/lib/utils.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/common/include/villas/utils.hpp b/common/include/villas/utils.hpp index ce6defa42..99f59a2cf 100644 --- a/common/include/villas/utils.hpp +++ b/common/include/villas/utils.hpp @@ -163,11 +163,11 @@ char *strcatf(char **dest, const char *fmt, ...) __attribute__((format(printf, 2, 3))); // Variadic version of strcatf() -char *vstrcatf(char **dest, const char *fmt, va_list va) +char *vstrcatf(char **dest, const char *fmt, va_list &va) __attribute__((format(printf, 2, 0))); char *strf(const char *fmt, ...); -char *vstrf(const char *fmt, va_list va); +char *vstrf(const char *fmt, va_list &va); // Allocate and copy memory. void *memdup(const void *src, size_t bytes); diff --git a/common/lib/utils.cpp b/common/lib/utils.cpp index 61666029a..fe523de48 100644 --- a/common/lib/utils.cpp +++ b/common/lib/utils.cpp @@ -194,7 +194,7 @@ double boxMuller(float m, float s) { double randf() { return (double)random() / RAND_MAX; } -char *vstrcatf(char **dest, const char *fmt, va_list ap) { +char *vstrcatf(char **dest, const char *fmt, va_list &ap) { char *tmp; int n = *dest ? strlen(*dest) : 0; int i = vasprintf(&tmp, fmt, ap); @@ -228,7 +228,7 @@ char *strf(const char *fmt, ...) { return buf; } -char *vstrf(const char *fmt, va_list va) { +char *vstrf(const char *fmt, va_list &va) { char *buf = nullptr; vstrcatf(&buf, fmt, va); From 844a1c12e9b43340c484cdc71854cad37982a033 Mon Sep 17 00:00:00 2001 From: Pascal Bauer Date: Thu, 26 Jun 2025 12:04:27 +0200 Subject: [PATCH 2/2] fix: vstrcatf wil leave va_list parameter valid after use vstrcatf now copies the va_list parameter to prevent it beeing undetermined after call to vasprintf. See full desciption in #678. Signed-off-by: Pascal Bauer --- common/lib/utils.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/common/lib/utils.cpp b/common/lib/utils.cpp index fe523de48..e5422a882 100644 --- a/common/lib/utils.cpp +++ b/common/lib/utils.cpp @@ -197,7 +197,21 @@ double randf() { return (double)random() / RAND_MAX; } char *vstrcatf(char **dest, const char *fmt, va_list &ap) { char *tmp; int n = *dest ? strlen(*dest) : 0; - int i = vasprintf(&tmp, fmt, ap); + + va_list va_copy; + va_copy(va_copy, ap); + int i = vasprintf(&tmp, fmt, va_copy); + va_end(va_copy); + + // Advance va_list + const char *format = fmt; + if (strcmp(format, "%ju") == 0) { + va_arg(ap, unsigned int); + } else if (strcmp(format, "%lf") == 0) { + va_arg(ap, double); + } else if (strcmp(format, "%s") == 0) { + va_arg(ap, char *); + } *dest = (char *)(realloc(*dest, n + i + 1)); if (*dest != nullptr)