vasnprintf: Fix crash in %ls directive.
[pspp] / lib / vasnprintf.c
index 79854ed87835f5389e8a4cc47d95a55c5e498a60..f0144a2b12e98d1fc97d86c928de4d232c7b29bc 100644 (file)
 # define USE_SNPRINTF 1
 # if HAVE_DECL__SNWPRINTF
    /* On Windows, the function swprintf() has a different signature than
-      on Unix; we use the _snwprintf() function instead.  */
-#  define SNPRINTF _snwprintf
+      on Unix; we use the function _snwprintf() or - on mingw - snwprintf()
+      instead.  The mingw function snwprintf() has fewer bugs than the
+      MSVCRT function _snwprintf(), so prefer that.  */
+#  if defined __MINGW32__
+#   define SNPRINTF snwprintf
+#  else
+#   define SNPRINTF _snwprintf
+#  endif
 # else
    /* Unix.  */
 #  define SNPRINTF swprintf
 #  define USE_SNPRINTF 0
 # endif
 # if HAVE_DECL__SNPRINTF
-   /* Windows.  */
-#  define SNPRINTF _snprintf
+   /* Windows.  The mingw function snprintf() has fewer bugs than the MSVCRT
+      function _snprintf(), so prefer that.  */
+#  if defined __MINGW32__
+#   define SNPRINTF snprintf
+    /* Here we need to call the native snprintf, not rpl_snprintf.  */
+#   undef snprintf
+#  else
+#   define SNPRINTF _snprintf
+#  endif
 # else
    /* Unix.  */
 #  define SNPRINTF snprintf
@@ -2592,8 +2605,16 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                           count = wctomb (cbuf, *arg);
 #   endif
                           if (count <= 0)
-                            /* Inconsistency.  */
-                            abort ();
+                            {
+                              /* Cannot convert.  */
+                              if (!(result == resultbuf || result == NULL))
+                                free (result);
+                              if (buf_malloced != NULL)
+                                free (buf_malloced);
+                              CLEANUP ();
+                              errno = EILSEQ;
+                              return NULL;
+                            }
                           ENSURE_ALLOCATION (xsum (length, count));
                           memcpy (result + length, cbuf, count);
                           length += count;