diff options
author | tjr <tjr@FreeBSD.org> | 2002-09-26 07:55:18 +0000 |
---|---|---|
committer | tjr <tjr@FreeBSD.org> | 2002-09-26 07:55:18 +0000 |
commit | aecdb4ddca551dbce73b6783fe3cf6fb5ecd9aa1 (patch) | |
tree | 3a0bc982a80e04afb5805194e42fabd39197e095 /lib/libc | |
parent | 536752d4811eec3de96155aaa1aa24b60ec8cfe9 (diff) | |
download | FreeBSD-src-aecdb4ddca551dbce73b6783fe3cf6fb5ecd9aa1.zip FreeBSD-src-aecdb4ddca551dbce73b6783fe3cf6fb5ecd9aa1.tar.gz |
Sync with OpenBSD: avoid memory leak when __vfprintf() fails because it
runs out of memory, always call va_end.
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/stdio/asprintf.c | 32 | ||||
-rw-r--r-- | lib/libc/stdio/vasprintf.c | 31 |
2 files changed, 39 insertions, 24 deletions
diff --git a/lib/libc/stdio/asprintf.c b/lib/libc/stdio/asprintf.c index 95c22b6..214405e 100644 --- a/lib/libc/stdio/asprintf.c +++ b/lib/libc/stdio/asprintf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: asprintf.c,v 1.4 1998/06/21 22:13:46 millert Exp $ */ +/* $OpenBSD: asprintf.c,v 1.8 2002/02/19 19:39:36 millert Exp $ */ /* * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com> @@ -44,27 +44,35 @@ asprintf(char **str, char const *fmt, ...) va_list ap; FILE f; struct __sFILEX ext; + unsigned char *_base; va_start(ap, fmt); f._file = -1; f._flags = __SWR | __SSTR | __SALC; f._bf._base = f._p = (unsigned char *)malloc(128); - if (f._bf._base == NULL) { - *str = NULL; - errno = ENOMEM; - return (-1); - } + if (f._bf._base == NULL) + goto err; f._bf._size = f._w = 127; /* Leave room for the NUL */ f._extra = &ext; INITEXTRA(&f); ret = __vfprintf(&f, fmt, ap); /* Use unlocked __vfprintf */ + if (ret == -1) + goto err; *f._p = '\0'; + _base = realloc(f._bf._base, ret + 1); + if (_base == NULL) + goto err; + *str = (char *)_base; va_end(ap); - f._bf._base = reallocf(f._bf._base, f._bf._size + 1); - if (f._bf._base == NULL) { - errno = ENOMEM; - ret = -1; - } - *str = (char *)f._bf._base; return (ret); + +err: + va_end(ap); + if (f._bf._base != NULL) { + free(f._bf._base); + f._bf._base = NULL; + } + *str = NULL; + errno = ENOMEM; + return (-1); } diff --git a/lib/libc/stdio/vasprintf.c b/lib/libc/stdio/vasprintf.c index 9e8efcf..2d2f9e0 100644 --- a/lib/libc/stdio/vasprintf.c +++ b/lib/libc/stdio/vasprintf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vasprintf.c,v 1.4 1998/06/21 22:13:47 millert Exp $ */ +/* $OpenBSD: vasprintf.c,v 1.6 1998/10/16 16:11:56 millert Exp $ */ /* * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com> @@ -44,25 +44,32 @@ vasprintf(str, fmt, ap) int ret; FILE f; struct __sFILEX ext; + unsigned char *_base; f._file = -1; f._flags = __SWR | __SSTR | __SALC; f._bf._base = f._p = (unsigned char *)malloc(128); - if (f._bf._base == NULL) { - *str = NULL; - errno = ENOMEM; - return (-1); - } + if (f._bf._base == NULL) + goto err; f._bf._size = f._w = 127; /* Leave room for the NUL */ f._extra = &ext; INITEXTRA(&f); ret = __vfprintf(&f, fmt, ap); + if (ret == -1) + goto err; *f._p = '\0'; - f._bf._base = reallocf(f._bf._base, f._bf._size + 1); - if (f._bf._base == NULL) { - errno = ENOMEM; - ret = -1; - } - *str = (char *)f._bf._base; + _base = realloc(f._bf._base, ret + 1); + if (_base == NULL) + goto err; + *str = (char *)_base; return (ret); + +err: + if (f._bf._base != NULL) { + free(f._bf._base); + f._bf._base = NULL; + } + *str = NULL; + errno = ENOMEM; + return (-1); } |