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.
Esse commit está contido em:
Martin Willers
2014-05-08 12:32:56 +02:00
commit de Benjamin Dobell
commit d5cd49b73c
+42 -30
Ver Arquivo
@@ -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)