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:
commit de
Benjamin Dobell
pai
9f957a1937
commit
d5cd49b73c
@@ -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)
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário