From 3383deca89b096faaebf065ba1a4be55ea1b46f4 Mon Sep 17 00:00:00 2001 From: "Tim J. Robbins" Date: Thu, 26 Sep 2002 07:55:18 +0000 Subject: Sync with OpenBSD: avoid memory leak when __vfprintf() fails because it runs out of memory, always call va_end. --- lib/libc/stdio/asprintf.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) (limited to 'lib/libc/stdio/asprintf.c') diff --git a/lib/libc/stdio/asprintf.c b/lib/libc/stdio/asprintf.c index 95c22b62a4da..214405e488f5 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 @@ -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); } -- cgit v1.2.3