aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Willers <M.Willers@gmx.net>2014-05-08 12:32:56 +0200
committerBenjamin Dobell <benjamin.dobell+git@glassechidna.com.au>2014-05-10 01:22:22 +1000
commitd5cd49b73c3dfaf5b1188030a6bc9fc597edae8a (patch)
treed7ac13957f87aabbc6e5702de34fffa6d4ffcc25
parent9f957a193701788cac66292daea2c89ed94a033f (diff)
downloadexternal_heimdall-d5cd49b73c3dfaf5b1188030a6bc9fc597edae8a.zip
external_heimdall-d5cd49b73c3dfaf5b1188030a6bc9fc597edae8a.tar.gz
external_heimdall-d5cd49b73c3dfaf5b1188030a6bc9fc597edae8a.tar.bz2
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.
-rw-r--r--heimdall/source/Interface.cpp72
1 files 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)