Fix out-of-memory handling of vasnprintf.
authorBruno Haible <bruno@clisp.org>
Sat, 3 Nov 2007 11:40:53 +0000 (12:40 +0100)
committerBruno Haible <bruno@clisp.org>
Sat, 3 Nov 2007 11:40:53 +0000 (12:40 +0100)
ChangeLog
lib/printf-parse.c
lib/vasnprintf.c

index df6a7f4..15cd4c7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2007-11-03  Bruno Haible  <bruno@clisp.org>
+
+       Fix out-of-memory handling of vasnprintf.
+       * lib/printf-parse.c: Include <errno.h>.
+       (PRINTF_PARSE): When failing, set errno to EINVAL or ENOMEM.
+       * lib/vasnprintf.c (VASNPRINTF): When PRINTF_PARSE fails, assume errno
+       is already set.
+
 2007-11-02  Eric Blake  <ebb9@byu.net>
 
        Fix tests on cygwin.
index 9e9880c..e3aa95a 100644 (file)
@@ -63,6 +63,9 @@
 /* malloc(), realloc(), free().  */
 #include <stdlib.h>
 
+/* errno.  */
+#include <errno.h>
+
 /* Checked size_t computations.  */
 #include "xsize.h"
 
@@ -89,7 +92,7 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
   d->dir = (DIRECTIVE *) malloc (d_allocated * sizeof (DIRECTIVE));
   if (d->dir == NULL)
     /* Out of memory.  */
-    return -1;
+    goto out_of_memory_1;
 
   a->count = 0;
   a_allocated = 0;
@@ -109,13 +112,13 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
        memory_size = xtimes (a_allocated, sizeof (argument));          \
        if (size_overflow_p (memory_size))                              \
          /* Overflow, would lead to out of memory.  */                 \
-         goto error;                                                   \
+         goto out_of_memory;                                           \
        memory = (argument *) (a->arg                                   \
                               ? realloc (a->arg, memory_size)          \
                               : malloc (memory_size));                 \
        if (memory == NULL)                                             \
          /* Out of memory.  */                                         \
-         goto error;                                                   \
+         goto out_of_memory;                                           \
        a->arg = memory;                                                \
       }                                                                        \
     while (a->count <= n)                                              \
@@ -539,11 +542,11 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
              memory_size = xtimes (d_allocated, sizeof (DIRECTIVE));
              if (size_overflow_p (memory_size))
                /* Overflow, would lead to out of memory.  */
-               goto error;
+               goto out_of_memory;
              memory = (DIRECTIVE *) realloc (d->dir, memory_size);
              if (memory == NULL)
                /* Out of memory.  */
-               goto error;
+               goto out_of_memory;
              d->dir = memory;
            }
        }
@@ -566,6 +569,16 @@ error:
     free (a->arg);
   if (d->dir)
     free (d->dir);
+  errno = EINVAL;
+  return -1;
+
+out_of_memory:
+  if (a->arg)
+    free (a->arg);
+  if (d->dir)
+    free (d->dir);
+out_of_memory_1:
+  errno = ENOMEM;
   return -1;
 }
 
index 42d0e74..f081e3a 100644 (file)
@@ -1196,10 +1196,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
   arguments a;
 
   if (PRINTF_PARSE (format, &d, &a) < 0)
-    {
-      errno = EINVAL;
-      return NULL;
-    }
+    /* errno is already set.  */
+    return NULL;
 
 #define CLEANUP() \
   free (d.dir);                                                                \