diff options
| author | Peter Wemm <peter@FreeBSD.org> | 1997-07-06 08:42:37 +0000 | 
|---|---|---|
| committer | Peter Wemm <peter@FreeBSD.org> | 1997-07-06 08:42:37 +0000 | 
| commit | e48f3cfbfc83b4d0c4fa376c316a3da03d867722 (patch) | |
| tree | 8bb3b6c9609546e2de78e00d086e817b3745147e /lib/libc/stdio/vasprintf.c | |
| parent | 2b3b4e02a9162710b9ab6d7ec0a50d1c0b08bcb5 (diff) | |
Notes
Diffstat (limited to 'lib/libc/stdio/vasprintf.c')
| -rw-r--r-- | lib/libc/stdio/vasprintf.c | 37 | 
1 files changed, 29 insertions, 8 deletions
| diff --git a/lib/libc/stdio/vasprintf.c b/lib/libc/stdio/vasprintf.c index fde3d8b0acfe..7b75b2c653b4 100644 --- a/lib/libc/stdio/vasprintf.c +++ b/lib/libc/stdio/vasprintf.c @@ -24,7 +24,7 @@   */  #if defined(LIBC_RCS) && !defined(lint) -static char rcsid[] = "$Id: vasprintf.c,v 1.5 1997/02/22 15:02:39 peter Exp $"; +static char rcsid[] = "$Id: vasprintf.c,v 1.6 1997/07/06 07:54:56 peter Exp $";  #endif /* LIBC_RCS and not lint */  #include <stdio.h> @@ -104,17 +104,38 @@ vasprintf(str, fmt, ap)  	}  	ret = vfprintf(f, fmt, ap);  	fclose(f); -	if (ret < 0) { + +	/* +	 * clean up the wreckage. Did writehook fail or did something else +	 * in stdio explode perhaps? +	 */ +	if (h.base == NULL)	/* realloc failed in writehook */ +		return (-1); +	if (ret < 0) {		/* something else? */  		free(h.base);  		return (-1);  	} -	if (h.base == NULL)	/* failed to realloc in writehook */ -		return (-1); -	*str = realloc(h.base, (size_t)(h.size - h.left + 1)); -	if (*str == NULL) {	/* failed to realloc it to actual size */ -		free(h.base); -		return (-1); +	/* +	 * At this point, we have a non-null terminated string in a +	 * buffer.  There may not be enough room to null-terminate it +	 * (h.left == 0) - if realloc failes to expand it, it's fatal. +	 * If we were merely trying to shrink the buffer, a realloc failure +	 * is not [yet] fatal. Note that when realloc returns NULL, +	 * the original buffer is left allocated and valid. +	 */ +	if (h.left == 1)	/* exact fit, do not realloc */ +		*str = h.base; +	else { +		*str = realloc(h.base, (size_t)(h.size - h.left + 1)); +		if (*str == NULL) { +			/* failed to expand? - fatal */ +			if (h.left == 0) { +				free(h.base); +				return (-1); +			} +			*str = h.base;	/* use oversize original buffer */ +		}  	}  	(*str)[h.size - h.left] = '\0';  	return (ret); | 
