msvcrt: Correctly manage va_list:s in vf(w)printf ny using auto-grow buffer in prinf engine.
This commit is contained in:
parent
1eaae093e2
commit
4d86e49173
|
@ -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);
|
||||||
|
|
||||||
|
sz = MultiByteToWideChar( CP_ACP, 0, format, -1, NULL, 0 );
|
||||||
|
formatW = HeapAlloc( GetProcessHeap(), 0, sz*sizeof(WCHAR) );
|
||||||
|
MultiByteToWideChar( CP_ACP, 0, format, -1, formatW, sz );
|
||||||
|
|
||||||
|
if ((written = pf_vsnprintf( &out, formatW, NULL, FALSE, valist )) >= 0)
|
||||||
{
|
{
|
||||||
resize = (written == -1 ? resize * 2 : written + 1);
|
retval = MSVCRT_fwrite(out.buf.A, sizeof(*out.buf.A), written, file);
|
||||||
if (mem != buf)
|
|
||||||
MSVCRT_free (mem);
|
|
||||||
if (!(mem = MSVCRT_malloc(resize)))
|
|
||||||
return MSVCRT_EOF;
|
|
||||||
}
|
}
|
||||||
retval = MSVCRT_fwrite(mem, sizeof(*mem), written, file);
|
else retval = -1;
|
||||||
if (mem != buf)
|
|
||||||
MSVCRT_free (mem);
|
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
|
||||||
*/
|
*/
|
||||||
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;
|
||||||
|
out.used = 0;
|
||||||
|
out.len = sizeof(buf) / sizeof(buf[0]);
|
||||||
|
|
||||||
|
if ((written = pf_vsnprintf( &out, format, NULL, FALSE, valist )) >= 0)
|
||||||
{
|
{
|
||||||
resize = (written == -1 ? resize * 2 : written + sizeof(MSVCRT_wchar_t));
|
retval = MSVCRT_fwrite(out.buf.W, sizeof(*out.buf.W), written, file);
|
||||||
if (mem != buf)
|
|
||||||
MSVCRT_free (mem);
|
|
||||||
if (!(mem = MSVCRT_malloc(resize*sizeof(*mem))))
|
|
||||||
return MSVCRT_EOF;
|
|
||||||
}
|
}
|
||||||
retval = MSVCRT_fwrite(mem, sizeof(*mem), written, file);
|
else retval = -1;
|
||||||
if (mem != buf)
|
if (out.buf.W != out.grow.W)
|
||||||
MSVCRT_free (mem);
|
MSVCRT_free (out.buf.W);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue