msvcrt: Estimate required buffer size better in pf_vsnprintf.

This commit is contained in:
Jesse Allen 2006-11-13 20:55:02 -07:00 committed by Alexandre Julliard
parent fa8656f841
commit 5b75c86921
1 changed files with 33 additions and 9 deletions

View File

@ -281,6 +281,7 @@ static inline int pf_output_stringA( pf_output *out, LPCSTR str, int len )
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 )
{
int i, r = 0;
@ -426,15 +427,19 @@ static void pf_rebuild_format_string( char *p, pf_flags *flags )
*p++ = 0;
}
/* pf_integer_conv: prints x to buf, including alternate formats,
but not the sign */
static void pf_integer_conv( char *buf, pf_flags *flags, LONGLONG x )
/* pf_integer_conv: prints x to buf, including alternate formats and
additional precision digits, but not field characters or the sign */
static void pf_integer_conv( char *buf, int buf_len, pf_flags *flags,
LONGLONG x )
{
unsigned int base;
const char *digits;
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;
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 */
flags->Precision = strlen( buf );
if( tmp != number )
HeapFree( GetProcessHeap(), 0, tmp );
return;
}
@ -660,10 +668,18 @@ static int pf_vsnprintf( pf_output *out, const WCHAR *format, va_list valist )
{
char number[40], *x = number;
if( flags.FieldLength >= sizeof number )
x = HeapAlloc( GetProcessHeap(), 0, flags.FieldLength+1 );
/* Estimate largest possible required buffer size:
* 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 );
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;
if( flags.FieldLength >= sizeof number )
x = HeapAlloc( GetProcessHeap(), 0, flags.FieldLength+1 );
/* Estimate largest possible required buffer size:
* 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 );