[libcxx-commits] [PATCH] D97473: [SystemZ][z/OS] vasprintf fix libc++

Muiez Ahmed via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Thu Feb 25 06:49:23 PST 2021


muiez created this revision.
muiez added reviewers: libc++, zibi, ldionne.
muiez requested review of this revision.
Herald added a project: libc++.
Herald added a subscriber: libcxx-commits.
Herald added 1 blocking reviewer(s): libc++.

The aim is to use the correct vasprintf implementation for z/OS libc++, where a copy of va_list ap is needed. In particular, it avoids the potential that the initial internal call to vsnprintf will modify ap and the subsequent call to vsnprintf will use that modified ap.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D97473

Files:
  libcxx/include/__support/ibm/xlocale.h


Index: libcxx/include/__support/ibm/xlocale.h
===================================================================
--- libcxx/include/__support/ibm/xlocale.h
+++ libcxx/include/__support/ibm/xlocale.h
@@ -10,6 +10,7 @@
 #ifndef _LIBCPP_SUPPORT_IBM_XLOCALE_H
 #define _LIBCPP_SUPPORT_IBM_XLOCALE_H
 
+#include <stdarg.h>
 #include <__support/ibm/locale_mgmt_aix.h>
 
 #include "cstdlib"
@@ -251,21 +252,22 @@
 }
 
 static inline
-int vasprintf(char **strp, const char *fmt, va_list ap)
-{
-  const size_t buff_size = 256;
-  int str_size;
-  if ((*strp = (char *)malloc(buff_size)) == NULL)
-  {
-    return -1;
-  }
-  if ((str_size = vsnprintf(*strp, buff_size, fmt,  ap)) >= buff_size)
-  {
-    if ((*strp = (char *)realloc(*strp, str_size + 1)) == NULL)
-    {
-      return -1;
+int vasprintf(char **strp, const char *fmt, va_list ap) {
+  int str_size = -1;
+  va_list ap2;
+  va_copy(ap2, ap);
+  int count = vsnprintf(0, 0, fmt, ap2);
+  va_end(ap2);
+  if (count < 0) return -1;
+  const size_t buf_size = count + 1;
+  char *const buf = (char *)malloc(buf_size);
+  if (buf) {
+    *strp = buf;
+    str_size = vsnprintf(*strp, buf_size, fmt, ap);
+    if (str_size < 0 || (size_t)str_size >= buf_size) {
+      free(buf);
+      str_size = -1;
     }
-    str_size = vsnprintf(*strp, str_size + 1, fmt,  ap);
   }
   return str_size;
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D97473.326381.patch
Type: text/x-patch
Size: 1347 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20210225/4ca478de/attachment.bin>


More information about the libcxx-commits mailing list