changeset 29129:f666d9b1fdbd

Fix out-of-memory handling of vasnprintf.
author Bruno Haible <bruno@clisp.org>
date Sat, 03 Nov 2007 12:40:53 +0100
parents aa926a8978df
children 113c190cc217
files ChangeLog lib/printf-parse.c lib/vasnprintf.c
diffstat 3 files changed, 28 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Nov 02 16:28:00 2007 -0600
+++ b/ChangeLog	Sat Nov 03 12:40:53 2007 +0100
@@ -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.
--- a/lib/printf-parse.c	Fri Nov 02 16:28:00 2007 -0600
+++ b/lib/printf-parse.c	Sat Nov 03 12:40:53 2007 +0100
@@ -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 @@
   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 @@
 	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 @@
 	      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 @@
     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;
 }
 
--- a/lib/vasnprintf.c	Fri Nov 02 16:28:00 2007 -0600
+++ b/lib/vasnprintf.c	Sat Nov 03 12:40:53 2007 +0100
@@ -1196,10 +1196,8 @@
   arguments a;
 
   if (PRINTF_PARSE (format, &d, &a) < 0)
-    {
-      errno = EINVAL;
-      return NULL;
-    }
+    /* errno is already set.  */
+    return NULL;
 
 #define CLEANUP() \
   free (d.dir);								\