msvcrt: Estimate required buffer size better in pf_vsnprintf.
This commit is contained in:
parent
fa8656f841
commit
5b75c86921
|
@ -281,6 +281,7 @@ static inline int pf_output_stringA( pf_output *out, LPCSTR str, int len )
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* pf_fill: takes care of signs, alignment, zero and field padding */
|
||||||
static inline int pf_fill( pf_output *out, int len, pf_flags *flags, char left )
|
static inline int pf_fill( pf_output *out, int len, pf_flags *flags, char left )
|
||||||
{
|
{
|
||||||
int i, r = 0;
|
int i, r = 0;
|
||||||
|
@ -426,15 +427,19 @@ static void pf_rebuild_format_string( char *p, pf_flags *flags )
|
||||||
*p++ = 0;
|
*p++ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pf_integer_conv: prints x to buf, including alternate formats,
|
/* pf_integer_conv: prints x to buf, including alternate formats and
|
||||||
but not the sign */
|
additional precision digits, but not field characters or the sign */
|
||||||
static void pf_integer_conv( char *buf, pf_flags *flags, LONGLONG x )
|
static void pf_integer_conv( char *buf, int buf_len, pf_flags *flags,
|
||||||
|
LONGLONG x )
|
||||||
{
|
{
|
||||||
unsigned int base;
|
unsigned int base;
|
||||||
const char *digits;
|
const char *digits;
|
||||||
|
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
char tmp[40];
|
char number[40], *tmp = number;
|
||||||
|
|
||||||
|
if( buf_len > sizeof number )
|
||||||
|
tmp = HeapAlloc( GetProcessHeap(), 0, buf_len );
|
||||||
|
|
||||||
base = 10;
|
base = 10;
|
||||||
if( flags->Format == 'o' )
|
if( flags->Format == 'o' )
|
||||||
|
@ -487,6 +492,9 @@ static void pf_integer_conv( char *buf, pf_flags *flags, LONGLONG x )
|
||||||
/* Adjust precision so pf_fill won't truncate the number later */
|
/* Adjust precision so pf_fill won't truncate the number later */
|
||||||
flags->Precision = strlen( buf );
|
flags->Precision = strlen( buf );
|
||||||
|
|
||||||
|
if( tmp != number )
|
||||||
|
HeapFree( GetProcessHeap(), 0, tmp );
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -660,10 +668,18 @@ static int pf_vsnprintf( pf_output *out, const WCHAR *format, va_list valist )
|
||||||
{
|
{
|
||||||
char number[40], *x = number;
|
char number[40], *x = number;
|
||||||
|
|
||||||
if( flags.FieldLength >= sizeof number )
|
/* Estimate largest possible required buffer size:
|
||||||
x = HeapAlloc( GetProcessHeap(), 0, flags.FieldLength+1 );
|
* Chooses the larger of the field or precision
|
||||||
|
* Includes extra bytes: 1 byte for null, 1 byte for sign,
|
||||||
|
4 bytes for exponent, 2 bytes for alternate formats, 1 byte
|
||||||
|
for a decimal, and 1 byte for an additional float digit. */
|
||||||
|
int x_len = ((flags.FieldLength > flags.Precision) ?
|
||||||
|
flags.FieldLength : flags.Precision) + 10;
|
||||||
|
|
||||||
pf_integer_conv( x, &flags, va_arg(valist, LONGLONG) );
|
if( x_len >= sizeof number)
|
||||||
|
x = HeapAlloc( GetProcessHeap(), 0, x_len );
|
||||||
|
|
||||||
|
pf_integer_conv( x, x_len, &flags, va_arg(valist, LONGLONG) );
|
||||||
|
|
||||||
r = pf_output_format_A( out, x, -1, &flags );
|
r = pf_output_format_A( out, x, -1, &flags );
|
||||||
if( x != number )
|
if( x != number )
|
||||||
|
@ -675,8 +691,16 @@ static int pf_vsnprintf( pf_output *out, const WCHAR *format, va_list valist )
|
||||||
{
|
{
|
||||||
char fmt[20], number[40], *x = number;
|
char fmt[20], number[40], *x = number;
|
||||||
|
|
||||||
if( flags.FieldLength >= sizeof number )
|
/* Estimate largest possible required buffer size:
|
||||||
x = HeapAlloc( GetProcessHeap(), 0, flags.FieldLength+1 );
|
* Chooses the larger of the field or precision
|
||||||
|
* Includes extra bytes: 1 byte for null, 1 byte for sign,
|
||||||
|
4 bytes for exponent, 2 bytes for alternate formats, 1 byte
|
||||||
|
for a decimal, and 1 byte for an additional float digit. */
|
||||||
|
int x_len = ((flags.FieldLength > flags.Precision) ?
|
||||||
|
flags.FieldLength : flags.Precision) + 10;
|
||||||
|
|
||||||
|
if( x_len >= sizeof number)
|
||||||
|
x = HeapAlloc( GetProcessHeap(), 0, x_len );
|
||||||
|
|
||||||
pf_rebuild_format_string( fmt, &flags );
|
pf_rebuild_format_string( fmt, &flags );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue