This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

memory leak in vfprintf() when using %Id directive


Hi,

The implementation of 'I' in glibc allows this flag to allow multiple
times in a format directive, and after each, a width and precision is
allowed. This is not useful for the user, but leads to a memory leak.

============================= memleak.c =========================
#include <stdio.h>
#include <locale.h>

int main ()
{
  char buf[100000];
  int i;

  setlocale (LC_ALL, "fa_IR");
  for (i = 0; i < 10000; i++)
    if (sprintf (buf, "Got %I80000.70000I80000.70000I80000.70000I80000.70000Id of them.\n", 3) < 0)
      perror ("sprintf");
  //puts (buf);
  return 0;
}
==================================================================

$ gcc -O memleak.c
$ ./a.out

This process allocates a heap of 1.4 GB virtual size and ca. 128 MB of real
memory, i.e. 12800 bytes per call. The consumer is the malloc call in
glibc/stdio-common/vfprintf.c:1479.

Here is a patch that
  - disallows the 'I' after width and precision, thus making the implementation
    agree with the documentation in the printf.3 manual page,
  - thus removes the memory leak.


2004-01-11  Bruno Haible  <bruno@clisp.org>

	* stdio-common/vfprintf.c (vfprintf): Disallow the 'I' flag after
	width or precision has been seen.

--- glibc-20031205/stdio-common/vfprintf.c.bak	2003-12-05 12:57:06.000000000 +0100
+++ glibc-20031205/stdio-common/vfprintf.c	2004-01-11 23:29:42.000000000 +0100
@@ -399,7 +399,7 @@
       REF (form_floathex),	/* for 'A', 'a' */			      \
       REF (mod_ptrdiff_t),      /* for 't' */				      \
       REF (mod_intmax_t),       /* for 'j' */				      \
-      REF (flag_i18n)	        /* for 'I' */				      \
+      REF (form_unknown)        /* for 'I' */				      \
     };									      \
     /* Step 2: after processing precision.  */				      \
     static JUMP_TABLE_TYPE step2_jumps[30] =				      \
@@ -433,7 +433,7 @@
       REF (form_floathex),	/* for 'A', 'a' */			      \
       REF (mod_ptrdiff_t),      /* for 't' */				      \
       REF (mod_intmax_t),       /* for 'j' */				      \
-      REF (flag_i18n)	        /* for 'I' */				      \
+      REF (form_unknown)        /* for 'I' */				      \
     };									      \
     /* Step 3a: after processing first 'h' modifier.  */		      \
     static JUMP_TABLE_TYPE step3a_jumps[30] =				      \


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]