memory leak in vfprintf() when using %Id directive
Bruno Haible
bruno@clisp.org
Mon Jan 12 12:09:00 GMT 2004
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] = \
More information about the Libc-alpha
mailing list