[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