Rework previous commit.. I was confused by the number of diffs in the PR

and forgot what I was trying to do originally and accidently zapped
a feature. :-]  The problem is that we are converting a counted buffer in
a malloc pool into a null terminated C-style string.  I was calling realloc
originally to shrink the buffer to the desired size.  If realloc failed, we
still returned the valid buffer - the only thing wrong was it was a tad
too large.  The previous commit disabled this.

This commit now handles the three cases..
1: the buffer is exactly right for the null byte to terminate the
string (we don't call realloc).
2: it's got h.left = 0, so we must expand it to make room. If realloc
fails here, it's fatal.
3: if there's too much room, we realloc to shrink it - a failed realloc
is not fatal, we use the original buffer which is still valid.
This commit is contained in:
Peter Wemm 1997-07-06 08:42:37 +00:00
parent 2b3b4e02a9
commit e48f3cfbfc

View file

@ -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);