Fix issue in richio.cpp, when printing strings with a size > 500 chars.
This was due to an use of twice the same va_list by 2 calls to vsnprintf, but the first call can change the va_list.
This commit is contained in:
parent
a8bffb862c
commit
a928bbfaac
|
@ -3,7 +3,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2011 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
* Copyright (C) 2007-2011 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||||
* Copyright (C) 2007 KiCad Developers, see change_log.txt for contributors.
|
* Copyright (C) 2015 KiCad Developers, see change_log.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -43,6 +43,14 @@
|
||||||
static int vprint( std::string* result, const char* format, va_list ap )
|
static int vprint( std::string* result, const char* format, va_list ap )
|
||||||
{
|
{
|
||||||
char msg[512];
|
char msg[512];
|
||||||
|
// This function can call vsnprintf twice.
|
||||||
|
// But internally, vsnprintf retrieves arguments from the va_list identified by arg as if
|
||||||
|
// va_arg was used on it, and thus the state of the va_list is likely to be altered by the call.
|
||||||
|
// see: www.cplusplus.com/reference/cstdio/vsnprintf
|
||||||
|
// we make a copy of va_list ap for the second call, if happens
|
||||||
|
va_list tmp;
|
||||||
|
va_copy( tmp, ap );
|
||||||
|
|
||||||
size_t len = vsnprintf( msg, sizeof(msg), format, ap );
|
size_t len = vsnprintf( msg, sizeof(msg), format, ap );
|
||||||
|
|
||||||
if( len < sizeof(msg) ) // the output fit into msg
|
if( len < sizeof(msg) ) // the output fit into msg
|
||||||
|
@ -58,11 +66,13 @@ static int vprint( std::string* result, const char* format, va_list ap )
|
||||||
|
|
||||||
buf.reserve( len+1 ); // reserve(), not resize() which writes. +1 for trailing nul.
|
buf.reserve( len+1 ); // reserve(), not resize() which writes. +1 for trailing nul.
|
||||||
|
|
||||||
len = vsnprintf( &buf[0], len+1, format, ap );
|
len = vsnprintf( &buf[0], len+1, format, tmp );
|
||||||
|
|
||||||
result->append( &buf[0], &buf[0] + len );
|
result->append( &buf[0], &buf[0] + len );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
va_end( tmp ); // Release the temporary va_list, initialised from ap
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -397,13 +407,23 @@ const char* OUTPUTFORMATTER::GetQuoteChar( const char* wrapee )
|
||||||
|
|
||||||
int OUTPUTFORMATTER::vprint( const char* fmt, va_list ap ) throw( IO_ERROR )
|
int OUTPUTFORMATTER::vprint( const char* fmt, va_list ap ) throw( IO_ERROR )
|
||||||
{
|
{
|
||||||
|
// This function can call vsnprintf twice.
|
||||||
|
// But internally, vsnprintf retrieves arguments from the va_list identified by arg as if
|
||||||
|
// va_arg was used on it, and thus the state of the va_list is likely to be altered by the call.
|
||||||
|
// see: www.cplusplus.com/reference/cstdio/vsnprintf
|
||||||
|
// we make a copy of va_list ap for the second call, if happens
|
||||||
|
va_list tmp;
|
||||||
|
va_copy( tmp, ap );
|
||||||
int ret = vsnprintf( &buffer[0], buffer.size(), fmt, ap );
|
int ret = vsnprintf( &buffer[0], buffer.size(), fmt, ap );
|
||||||
|
|
||||||
if( ret >= (int) buffer.size() )
|
if( ret >= (int) buffer.size() )
|
||||||
{
|
{
|
||||||
buffer.resize( ret + 2000 );
|
buffer.resize( ret + 1000 );
|
||||||
ret = vsnprintf( &buffer[0], buffer.size(), fmt, ap );
|
ret = vsnprintf( &buffer[0], buffer.size(), fmt, tmp );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
va_end( tmp ); // Release the temporary va_list, initialised from ap
|
||||||
|
|
||||||
if( ret > 0 )
|
if( ret > 0 )
|
||||||
write( &buffer[0], ret );
|
write( &buffer[0], ret );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue