Commit 4d86e491 authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

msvcrt: Correctly manage va_list:s in vf(w)printf ny using auto-grow buffer in prinf engine.

parent 1eaae093
...@@ -3333,25 +3333,31 @@ MSVCRT_FILE* CDECL MSVCRT_tmpfile(void) ...@@ -3333,25 +3333,31 @@ MSVCRT_FILE* CDECL MSVCRT_tmpfile(void)
*/ */
int CDECL MSVCRT_vfprintf(MSVCRT_FILE* file, const char *format, __ms_va_list valist) int CDECL MSVCRT_vfprintf(MSVCRT_FILE* file, const char *format, __ms_va_list valist)
{ {
char buf[2048], *mem = buf; char buf[2048];
int written, resize = sizeof(buf), retval; LPWSTR formatW = NULL;
/* There are two conventions for vsnprintf failing: DWORD sz;
* Return -1 if we truncated, or pf_output out;
* Return the number of bytes that would have been written int written, retval;
* The code below handles both cases
*/ out.unicode = FALSE;
while ((written = MSVCRT_vsnprintf(mem, resize, format, valist)) == -1 || out.buf.A = out.grow.A = buf;
written > resize) out.used = 0;
{ out.len = sizeof(buf);
resize = (written == -1 ? resize * 2 : written + 1);
if (mem != buf) sz = MultiByteToWideChar( CP_ACP, 0, format, -1, NULL, 0 );
MSVCRT_free (mem); formatW = HeapAlloc( GetProcessHeap(), 0, sz*sizeof(WCHAR) );
if (!(mem = MSVCRT_malloc(resize))) MultiByteToWideChar( CP_ACP, 0, format, -1, formatW, sz );
return MSVCRT_EOF;
} if ((written = pf_vsnprintf( &out, formatW, NULL, FALSE, valist )) >= 0)
retval = MSVCRT_fwrite(mem, sizeof(*mem), written, file); {
if (mem != buf) retval = MSVCRT_fwrite(out.buf.A, sizeof(*out.buf.A), written, file);
MSVCRT_free (mem); }
else retval = -1;
HeapFree( GetProcessHeap(), 0, formatW );
if (out.buf.A != out.grow.A)
MSVCRT_free (out.buf.A);
return retval; return retval;
} }
...@@ -3363,21 +3369,22 @@ int CDECL MSVCRT_vfprintf(MSVCRT_FILE* file, const char *format, __ms_va_list va ...@@ -3363,21 +3369,22 @@ int CDECL MSVCRT_vfprintf(MSVCRT_FILE* file, const char *format, __ms_va_list va
*/ */
int CDECL MSVCRT_vfwprintf(MSVCRT_FILE* file, const MSVCRT_wchar_t *format, __ms_va_list valist) int CDECL MSVCRT_vfwprintf(MSVCRT_FILE* file, const MSVCRT_wchar_t *format, __ms_va_list valist)
{ {
MSVCRT_wchar_t buf[2048], *mem = buf; MSVCRT_wchar_t buf[2048];
int written, resize = sizeof(buf) / sizeof(MSVCRT_wchar_t), retval; pf_output out;
/* See vfprintf comments */ int written, retval;
while ((written = MSVCRT_vsnwprintf(mem, resize, format, valist)) == -1 ||
written > resize) out.unicode = TRUE;
{ out.buf.W = out.grow.W = buf;
resize = (written == -1 ? resize * 2 : written + sizeof(MSVCRT_wchar_t)); out.used = 0;
if (mem != buf) out.len = sizeof(buf) / sizeof(buf[0]);
MSVCRT_free (mem);
if (!(mem = MSVCRT_malloc(resize*sizeof(*mem)))) if ((written = pf_vsnprintf( &out, format, NULL, FALSE, valist )) >= 0)
return MSVCRT_EOF; {
} retval = MSVCRT_fwrite(out.buf.W, sizeof(*out.buf.W), written, file);
retval = MSVCRT_fwrite(mem, sizeof(*mem), written, file); }
if (mem != buf) else retval = -1;
MSVCRT_free (mem); if (out.buf.W != out.grow.W)
MSVCRT_free (out.buf.W);
return retval; return retval;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment