[1/2] ntdll: Implement correct behaviour when a NULL buffer is passed to *printf
Sebastian Lackner
sebastian at fds-team.de
Tue Dec 17 15:00:42 CST 2013
This implements the same behaviour for the ntdll *printf functions as on
Windows.
_snprintf(NULL, 0, "format") --> length of the result string
Besides that it also fixes some other mistakes:
* fix incorrect value added to out->used in pf_output_stringA
* error checking of the RtlAllocateHeap result
Note: The current implementation really requires that out->used is
increased (beyond the output buffer size). Using a different behaviour
would break the code at the end of pf_vsnprintf.
pf_output_stringW( out, p, 1 );
return out->used - 1;
---
dlls/ntdll/printf.c | 34 +++++++++++++++++++++++++++-------
1 file changed, 27 insertions(+), 7 deletions(-)
-------------- next part --------------
From 78f3301bb2aaa86772e776a2ba94423826df960c Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian at fds-team.de>
Date: Mon, 16 Dec 2013 04:12:18 +0100
Subject: ntdll: Implement correct behaviour when a NULL buffer is passed to
*printf
---
dlls/ntdll/printf.c | 34 +++++++++++++++++++++++++++-------
1 file changed, 27 insertions(+), 7 deletions(-)
diff --git a/dlls/ntdll/printf.c b/dlls/ntdll/printf.c
index 0a27f7e..06e6d85 100644
--- a/dlls/ntdll/printf.c
+++ b/dlls/ntdll/printf.c
@@ -47,6 +47,7 @@ typedef struct pf_output_t
int len;
BOOL unicode;
union {
+ void *X;
LPWSTR W;
LPSTR A;
} buf;
@@ -72,7 +73,12 @@ static inline int pf_output_stringW( pf_output *out, LPCWSTR str, int len )
if( len < 0 )
len = strlenW( str );
- if( out->unicode )
+ if (!out->buf.X)
+ {
+ out->used += len;
+ return len;
+ }
+ else if( out->unicode )
{
LPWSTR p = out->buf.W + out->used;
@@ -110,7 +116,12 @@ static inline int pf_output_stringA( pf_output *out, LPCSTR str, int len )
if( len < 0 )
len = strlen( str );
- if( !out->unicode )
+ if (!out->buf.X)
+ {
+ out->used += len;
+ return len;
+ }
+ else if( !out->unicode )
{
LPSTR p = out->buf.A + out->used;
@@ -137,7 +148,7 @@ static inline int pf_output_stringA( pf_output *out, LPCSTR str, int len )
return len;
}
if (space > 0) RtlMultiByteToUnicodeN( p, space * sizeof(WCHAR), NULL, str, len );
- out->used += n;
+ out->used += n / sizeof(WCHAR);
}
return -1;
}
@@ -169,7 +180,7 @@ static inline int pf_fill( pf_output *out, int len, pf_flags *flags, char left )
}
}
- if( left && flags->Sign && !flags->PadZero )
+ if( left && flags->Sign && !flags->PadZero && (r>=0) )
r = pf_output_stringA( out, &flags->Sign, 1 );
return r;
@@ -300,7 +311,13 @@ static void pf_integer_conv( char *buf, int buf_len, pf_flags *flags,
char number[40], *tmp = number;
if( buf_len > sizeof number )
- tmp = RtlAllocateHeap( GetProcessHeap(), 0, buf_len );
+ {
+ if (!(tmp = RtlAllocateHeap( GetProcessHeap(), 0, buf_len )))
+ {
+ buf[0] = '\0';
+ return;
+ }
+ }
base = 10;
if( flags->Format == 'o' )
@@ -588,7 +605,8 @@ static int pf_vsnprintf( pf_output *out, const WCHAR *format, __ms_va_list valis
flags.FieldLength : flags.Precision) + 10;
if( x_len >= sizeof number)
- x = RtlAllocateHeap( GetProcessHeap(), 0, x_len );
+ if (!(x = RtlAllocateHeap( GetProcessHeap(), 0, x_len )))
+ return -1;
pf_integer_conv( x, x_len, &flags, va_arg(valist, LONGLONG) );
@@ -611,7 +629,8 @@ static int pf_vsnprintf( pf_output *out, const WCHAR *format, __ms_va_list valis
flags.FieldLength : flags.Precision) + 10;
if( x_len >= sizeof number)
- x = RtlAllocateHeap( GetProcessHeap(), 0, x_len );
+ if (!(x = RtlAllocateHeap( GetProcessHeap(), 0, x_len )))
+ return -1;
pf_rebuild_format_string( fmt, &flags );
--
1.7.9.5
More information about the wine-patches
mailing list