summary refs log tree commit diff
path: root/stdio-common
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2006-04-25 18:40:37 +0000
committerUlrich Drepper <drepper@redhat.com>2006-04-25 18:40:37 +0000
commitc7df983c08045b8d5c50f239b2b0d6e954afd2c7 (patch)
treec1794b194dfb415bf326359ef0504bb362fddbac /stdio-common
parent74ed1159d1588e7012e7c91dea8d85202ed715de (diff)
downloadglibc-c7df983c08045b8d5c50f239b2b0d6e954afd2c7.tar.gz
glibc-c7df983c08045b8d5c50f239b2b0d6e954afd2c7.tar.xz
glibc-c7df983c08045b8d5c50f239b2b0d6e954afd2c7.zip
[BZ #2072]
	* stdio-common/printf_fp.c: Fix potential memory leaks for
	malloc'ed wbuffer isn't freed in error conditions.
Diffstat (limited to 'stdio-common')
-rw-r--r--stdio-common/printf_fp.c34
1 files changed, 27 insertions, 7 deletions
diff --git a/stdio-common/printf_fp.c b/stdio-common/printf_fp.c
index 8a68f1948d..e4e32f9c28 100644
--- a/stdio-common/printf_fp.c
+++ b/stdio-common/printf_fp.c
@@ -72,7 +72,11 @@
     {									      \
       register const int outc = (ch);					      \
       if (putc (outc, fp) == EOF)					      \
-	return -1;							      \
+	{								      \
+	  if (buffer_malloced)						      \
+	    free (wbuffer);						      \
+	  return -1;							      \
+	}								      \
       ++done;								      \
     } while (0)
 
@@ -83,7 +87,11 @@
       if (len > 20)							      \
 	{								      \
 	  if (PUT (fp, wide ? (const char *) wptr : ptr, outlen) != outlen)   \
-	    return -1;							      \
+	    {								      \
+	      if (buffer_malloced)					      \
+		free (wbuffer);						      \
+	      return -1;						      \
+	    }								      \
 	  ptr += outlen;						      \
 	  done += outlen;						      \
 	}								      \
@@ -102,7 +110,11 @@
   do									      \
     {									      \
       if (PAD (fp, ch, len) != len)					      \
-	return -1;							      \
+	{								      \
+	  if (buffer_malloced)						      \
+	    free (wbuffer);						      \
+	  return -1;							      \
+	}								      \
       done += len;							      \
     }									      \
   while (0)
@@ -200,6 +212,11 @@ ___printf_fp (FILE *fp,
   /* Nonzero if this is output on a wide character stream.  */
   int wide = info->wide;
 
+  /* Buffer in which we produce the output.  */
+  wchar_t *wbuffer = NULL;
+  /* Flag whether wbuffer is malloc'ed or not.  */
+  int buffer_malloced = 0;
+
   auto wchar_t hack_digit (void);
 
   wchar_t hack_digit (void)
@@ -790,8 +807,7 @@ ___printf_fp (FILE *fp,
 
   {
     int width = info->width;
-    wchar_t *wbuffer, *wstartp, *wcp;
-    int buffer_malloced;
+    wchar_t *wstartp, *wcp;
     int chars_needed;
     int expscale;
     int intdig_max, intdig_no = 0;
@@ -1109,8 +1125,12 @@ ___printf_fp (FILE *fp,
 	      buffer = (char *) malloc (2 + chars_needed + decimal_len
 					+ ngroups * thousands_sep_len);
 	      if (buffer == NULL)
-		/* Signal an error to the caller.  */
-		return -1;
+		{
+		  /* Signal an error to the caller.  */
+		  if (buffer_malloced)
+		    free (wbuffer);
+		  return -1;
+		}
 	    }
 	  else
 	    buffer = (char *) alloca (2 + chars_needed + decimal_len