summaryrefslogtreecommitdiff
path: root/lib/libc/stdio/asprintf.c
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>1998-10-16 16:11:57 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>1998-10-16 16:11:57 +0000
commitf50a09c233e8e7b2e9000c583415a44b823cefca (patch)
tree3d23678fff9260b8b5bfced68ec1595d1f9bf002 /lib/libc/stdio/asprintf.c
parent3ab547365e08d79b236c282459c248a0dcfb07c2 (diff)
Make sure we free the buffer in all error cases. Do the final
realloc(3) to the size of the string, not the size of the buffer allocated for the string (which is a noop). mycroft@netbsd.org
Diffstat (limited to 'lib/libc/stdio/asprintf.c')
-rw-r--r--lib/libc/stdio/asprintf.c35
1 files changed, 20 insertions, 15 deletions
diff --git a/lib/libc/stdio/asprintf.c b/lib/libc/stdio/asprintf.c
index daca01a016d..fd0ba320c8f 100644
--- a/lib/libc/stdio/asprintf.c
+++ b/lib/libc/stdio/asprintf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: asprintf.c,v 1.5 1998/08/14 21:39:39 deraadt Exp $ */
+/* $OpenBSD: asprintf.c,v 1.6 1998/10/16 16:11:55 millert Exp $ */
/*
* Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
@@ -28,7 +28,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: asprintf.c,v 1.5 1998/08/14 21:39:39 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: asprintf.c,v 1.6 1998/10/16 16:11:55 millert Exp $";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
@@ -63,21 +63,26 @@ asprintf(str, fmt, va_alist)
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);
- }
- f._bf._size = f._w = 127; /* Leave room for the NULL */
+ if (f._bf._base == NULL)
+ goto err;
+ f._bf._size = f._w = 127; /* Leave room for the NUL */
ret = vfprintf(&f, fmt, ap);
+ if (ret == -1)
+ goto err;
*f._p = '\0';
va_end(ap);
- _base = realloc(f._bf._base, f._bf._size + 1);
- if (_base == NULL) {
- errno = ENOMEM;
- ret = -1;
- }
- f._bf._base = _base;
- *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) {
+ free(f._bf._base);
+ f._bf._base = NULL;
+ }
+ *str = NULL;
+ errno = ENOMEM;
+ return (-1);
}