On Friday 21 February 2020 17:22:13 Pali Rohár wrote:
> On Friday 21 February 2020 18:17:37 Liu Hao wrote:
> > 在 2020/2/21 2:27, Pali Rohár 写道:
> > > Hello! Based on raymod2 suggestion on IRC, I prepared full patch and
> > > tested it that snprintf() and vsnprintf() works correctly.
> > > 
> > > Patch is attached in email as jon_y on IRC suggested. I fixed directly
> > > __ms_snprintf() and __ms_vsnprintf() wrappers (around msvcrt's
> > > _snprintf()/_vsnprintf() calls) which are called by snprintf() and
> > > vsnprintf() static functions defined in stdio.h header file.
> > > 
> > > In patch I also removed vsnprintf == _vsnprintf and snprintf ==
> > > _snprintf aliases as they wrong, snprintf() is not same as msvcrt's
> > > _snprintf() function, and above __ms_snprintf() or __ms_vsnprintf()
> > > wrapper is needed.
> > > 
> > > PS: Please CC me as I'm not subscribed to list.
> > > 
> > 
> > Thanks. The patch looks good, except that the hunk for 'mingw-w64-tools'
> > had better be moved to an individual commit. I amended it and pushed.
> 
> Hello Liu! Thank you!

Hello! raymod2 on IRC pointed that _vscprintf() function used by above
patch is not provided by original VC6 msvcrt.dll library. It was
introduced in VC7 msvcr70.dll, but in may be provided in system32
msvcrt.dll. To workaround a problem when _vscprintf() is not available,
I wrote a small wrapper for libmingwex which emulates _vscprintf() call
via _vsnprintf() with temporary array. Patch is attached.

-- 
Pali Rohár
pali.ro...@gmail.com
diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am
index 308c1cef..353849fc 100644
--- a/mingw-w64-crt/Makefile.am
+++ b/mingw-w64-crt/Makefile.am
@@ -450,6 +450,7 @@ src_libmingwex=\
   stdio/_Exit.c            stdio/_findfirst64i32.c   stdio/_findnext64i32.c   stdio/_fstat.c \
   stdio/_fstat64i32.c      stdio/_ftime.c            stdio/_getc_nolock.c     stdio/_getwc_nolock.c     stdio/_putc_nolock.c    \
   stdio/_putwc_nolock.c    stdio/_stat.c             stdio/_stat64i32.c       stdio/_wfindfirst64i32.c  stdio/_wfindnext64i32.c \
+  stdio/_vscprintf.c       \
   stdio/_wstat.c           stdio/_wstat64i32.c       stdio/asprintf.c         stdio/atoll.c             stdio/fgetpos64.c       \
   stdio/fopen64.c          stdio/fseeko32.c          stdio/fseeko64.c         stdio/fsetpos64.c         stdio/ftello.c          \
   stdio/ftello64.c         stdio/ftruncate64.c       stdio/lltoa.c            stdio/lltow.c             stdio/lseek64.c         \
diff --git a/mingw-w64-crt/stdio/_vscprintf.c b/mingw-w64-crt/stdio/_vscprintf.c
index e69de29b..cec1841d 100644
--- a/mingw-w64-crt/stdio/_vscprintf.c
+++ b/mingw-w64-crt/stdio/_vscprintf.c
@@ -0,0 +1,55 @@
+#include <windows.h>
+#include <msvcrt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+static int __cdecl init_func(const char * __restrict__ format, va_list arglist);
+int (__cdecl *__MINGW_IMP_SYMBOL(_vscprintf))(const char * __restrict__, va_list) = init_func;
+
+static int __cdecl emu_func(const char * __restrict__ format, va_list arglist)
+{
+    char *buffer, *new_buffer;
+    size_t size;
+    int ret;
+
+    size = strlen(format) * 2;
+    buffer = malloc(size);
+
+    if (!buffer) {
+        _set_errno(ENOMEM);
+        return -1;
+    }
+
+    while ((ret = _vsnprintf(buffer, size, format, arglist)) < 0) {
+        size *= 2;
+        new_buffer = realloc(buffer, size);
+        if (!new_buffer)
+            break;
+        buffer = new_buffer;
+    }
+
+    free(buffer);
+
+    if (ret < 0) {
+        _set_errno(ENOMEM);
+        return -1;
+    }
+
+    return ret;
+}
+
+static int __cdecl init_func(const char * __restrict__ format, va_list arglist)
+{
+    HMODULE msvcrt = __mingw_get_msvcrt_handle();
+    int (__cdecl *func)(const char * __restrict__, va_list) = NULL;
+
+    if (msvcrt)
+        func = (void*)GetProcAddress(msvcrt, "_vscprintf");
+
+    if (!func)
+        func = emu_func;
+
+    return (__MINGW_IMP_SYMBOL(_vscprintf) = func)(format, arglist);
+}

Attachment: signature.asc
Description: PGP signature

_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to