From d5cd49b73c3dfaf5b1188030a6bc9fc597edae8a Mon Sep 17 00:00:00 2001 From: Martin Willers Date: Thu, 8 May 2014 12:32:56 +0200 Subject: fix --stdout-errors handling When using --stdout-errors, the messages written to stdout contained garbage. Inside vfprintf(), each va_arg() consumes one entry from the va_args. Trying to use the same va_args variable again results in undefined behavior as subsequent va_arg() invocations continue to read from memory past the actual variable space. Instead, a copy has to be made with va_copy() and this be used for outputting to stdout. --- heimdall/source/Interface.cpp | 72 +++++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 30 deletions(-) diff --git a/heimdall/source/Interface.cpp b/heimdall/source/Interface.cpp index 4a300ca..fd989fa 100644 --- a/heimdall/source/Interface.cpp +++ b/heimdall/source/Interface.cpp @@ -92,74 +92,86 @@ void Interface::Print(const char *format, ...) void Interface::PrintWarning(const char *format, ...) { - va_list args; - va_start(args, format); - - fprintf(stderr, "WARNING: "); - vfprintf(stderr, format, args); - fflush(stderr); + va_list stderrArgs; + va_start(stderrArgs, format); if (stdoutErrors) { + va_list stdoutArgs; + va_copy(stdoutArgs, stderrArgs); fprintf(stdout, "WARNING: "); - vfprintf(stdout, format, args); + vfprintf(stdout, format, stdoutArgs); fflush(stdout); + va_end(stdoutArgs); } - va_end(args); + fprintf(stderr, "WARNING: "); + vfprintf(stderr, format, stderrArgs); + fflush(stderr); + + va_end(stderrArgs); } void Interface::PrintWarningSameLine(const char *format, ...) { - va_list args; - va_start(args, format); - - vfprintf(stderr, format, args); - fflush(stderr); + va_list stderrArgs; + va_start(stderrArgs, format); if (stdoutErrors) { - vfprintf(stdout, format, args); + va_list stdoutArgs; + va_copy(stdoutArgs, stderrArgs); + vfprintf(stdout, format, stdoutArgs); fflush(stdout); + va_end(stdoutArgs); } - va_end(args); + vfprintf(stderr, format, stderrArgs); + fflush(stderr); + + va_end(stderrArgs); } void Interface::PrintError(const char *format, ...) { - va_list args; - va_start(args, format); - - fprintf(stderr, "ERROR: "); - vfprintf(stderr, format, args); - fflush(stderr); + va_list stderrArgs; + va_start(stderrArgs, format); if (stdoutErrors) { + va_list stdoutArgs; + va_copy(stdoutArgs, stderrArgs); fprintf(stdout, "ERROR: "); - vfprintf(stdout, format, args); + vfprintf(stdout, format, stdoutArgs); fflush(stdout); + va_end(stdoutArgs); } - va_end(args); + fprintf(stderr, "ERROR: "); + vfprintf(stderr, format, stderrArgs); + fflush(stderr); + + va_end(stderrArgs); } void Interface::PrintErrorSameLine(const char *format, ...) { - va_list args; - va_start(args, format); - - vfprintf(stderr, format, args); - fflush(stderr); + va_list stderrArgs; + va_start(stderrArgs, format); if (stdoutErrors) { - vfprintf(stdout, format, args); + va_list stdoutArgs; + va_copy(stdoutArgs, stderrArgs); + vfprintf(stdout, format, stdoutArgs); fflush(stdout); + va_end(stdoutArgs); } - va_end(args); + vfprintf(stderr, format, stderrArgs); + fflush(stderr); + + va_end(stderrArgs); } void Interface::PrintVersion(void) -- cgit v1.1