From 2f27687d8086d663f71f464fef5a03fbd6830d83 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Thu, 7 May 2026 22:10:23 -0700 Subject: [PATCH] Fix OSReport strings corruption with non-trivial format (#709) * Fix OSReport strings corruption with non-trivial format * Limit format attempts to 3 --- src/dusk/OSReport.cpp | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/src/dusk/OSReport.cpp b/src/dusk/OSReport.cpp index a54bcf0c78..aee1e17bc6 100644 --- a/src/dusk/OSReport.cpp +++ b/src/dusk/OSReport.cpp @@ -21,16 +21,39 @@ static bool checkEnabled() { return !__OSReport_disable || dusk::OSReportReallyForceEnable; } +#ifndef va_copy +#define va_copy(d, s) ((d) = (s)) +#endif + static std::string FormatToString(const char* msg, va_list list) { - int ret = vsnprintf(nullptr, 0, msg, list); - if (ret <= 0) { - return {}; + size_t size = (strlen(msg) * 2) + 50; + std::string str; + va_list ap; + int attempts = 0; + while (true) { + str.resize(size); + va_copy(ap, list); + int n = vsnprintf(str.data(), size, msg, ap); + va_end(ap); + if (n > -1 && n < size) { + str.resize(n); + break; + } + + ++attempts; + if (attempts >= 3) { + if (n == -1) { + str.clear(); + } + break; + } + if (n > -1) { + size = n + 1; + } else { + size *= 2; + } } - ++ret; - std::unique_ptr buf(new char[ret]); - vsnprintf(buf.get(), ret, msg, list); - buf[ret - 1] = '\0'; - return {buf.get()}; + return str; } void OSReport(const char* fmt, ...) {