Daniel Lehman : kernelbase: Pass va_list copy to internal RtlFormatMessage.

Alexandre Julliard julliard at winehq.org
Mon Jun 13 16:02:16 CDT 2022


Module: wine
Branch: master
Commit: 1714963a5f9e62deb7aaa8f751640cbf87d57993
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=1714963a5f9e62deb7aaa8f751640cbf87d57993

Author: Daniel Lehman <dlehman25 at gmail.com>
Date:   Sat Jun  4 08:03:02 2022 -0700

kernelbase: Pass va_list copy to internal RtlFormatMessage.

va_list passed to RtlFormatMessage is modified even on error in this
case, if the buffer is not large enough, STATUS_BUFFER_OVERFLOW is
returned and FormatMessage tries again, but the va_list pointer is now
moved to a later argument, so the next call reads off the end,
crashing.

Signed-off-by: Daniel Lehman <dlehman25 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/kernelbase/locale.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/dlls/kernelbase/locale.c b/dlls/kernelbase/locale.c
index 257d9f693ba..0c20c858a7a 100644
--- a/dlls/kernelbase/locale.c
+++ b/dlls/kernelbase/locale.c
@@ -5457,6 +5457,7 @@ DWORD WINAPI DECLSPEC_HOTPATCH FormatMessageW( DWORD flags, const void *source,
     if (flags & FORMAT_MESSAGE_ALLOCATE_BUFFER)
     {
         WCHAR *result;
+        va_list args_copy;
         ULONG alloc = max( size * sizeof(WCHAR), 65536 );
 
         for (;;)
@@ -5466,9 +5467,17 @@ DWORD WINAPI DECLSPEC_HOTPATCH FormatMessageW( DWORD flags, const void *source,
                 status = STATUS_NO_MEMORY;
                 break;
             }
-            status = RtlFormatMessage( src, width, !!(flags & FORMAT_MESSAGE_IGNORE_INSERTS),
-                                       FALSE, !!(flags & FORMAT_MESSAGE_ARGUMENT_ARRAY), args,
-                                       result, alloc, &retsize );
+            if (args && !(flags & FORMAT_MESSAGE_ARGUMENT_ARRAY))
+            {
+                va_copy( args_copy, *args );
+                status = RtlFormatMessage( src, width, !!(flags & FORMAT_MESSAGE_IGNORE_INSERTS),
+                                           FALSE, FALSE, &args_copy, result, alloc, &retsize );
+                va_end( args_copy );
+            }
+            else
+                status = RtlFormatMessage( src, width, !!(flags & FORMAT_MESSAGE_IGNORE_INSERTS),
+                                           FALSE, TRUE, args, result, alloc, &retsize );
+
             if (!status)
             {
                 if (retsize <= sizeof(WCHAR)) HeapFree( GetProcessHeap(), 0, result );




More information about the wine-cvs mailing list