From 41b96494c296410b610eac5e8bc6e1cf36c6a63e Mon Sep 17 00:00:00 2001 From: Diomendius <42310725+Diomendius@users.noreply.github.com> Date: Fri, 7 Jun 2024 22:20:34 +1200 Subject: [PATCH] Fix double-use of va_list in AppendFmt AppendFmt calls vsnprintf twice, first to check the size of the formatted string, then to write it for real, but it used the same va_list for both calls, so the second call got an invalid va_list after the first call had already consumed all its arguments. This is UB and at least on Linux makes the second call print garbage. I presume Windows implements va_list differently such that this somehow worked correctly, because on Linux, all of the dialog items get parsed into invalid JSON due to this bug, with lines like this (note the missing second array element and closing bracket): "pos" : [ -55947262, --- gpr2gpa/gpr2gpa.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gpr2gpa/gpr2gpa.cpp b/gpr2gpa/gpr2gpa.cpp index beb64c1..e532a99 100644 --- a/gpr2gpa/gpr2gpa.cpp +++ b/gpr2gpa/gpr2gpa.cpp @@ -98,6 +98,11 @@ void AppendFmt(std::vector &array, const char *fmt, ...) if (resultSize <= 0) return; + // vsnprintf invalidates the va_list, so we need to + // reinit args so the next call doesn't print garbage. + va_end(args); + va_start(args, fmt); + size_t appendSize = static_cast(resultSize); if (SIZE_MAX == appendSize)