diff --git a/src/utils/strbuf.c b/src/utils/strbuf.c
index df3ee4b236d7f41b716cec4ca6edb1f090086286..a48f7bc5765959d38050bdf2f19c027a9765f789 100644 (file)
--- a/src/utils/strbuf.c
+++ b/src/utils/strbuf.c
ssize_t
sdb_strbuf_vappend(sdb_strbuf_t *strbuf, const char *fmt, va_list ap)
{
+ va_list aq;
int status;
if ((! strbuf) || (! fmt))
if (strbuf_resize(strbuf))
return -1;
+ /* 'ap' is invalid after calling vsnprintf; thus copy before using it */
+ va_copy(aq, ap);
status = vsnprintf(strbuf->string + strbuf->pos,
strbuf->size - strbuf->pos, fmt, ap);
- if (status < 0)
+ if (status < 0) {
+ va_end(aq);
return status;
+ }
if ((size_t)status >= strbuf->size - strbuf->pos) {
strbuf_resize(strbuf);
/* reset string and try again */
strbuf->string[strbuf->pos] = '\0';
- return sdb_strbuf_vappend(strbuf, fmt, ap);
+ status = (int)sdb_strbuf_vappend(strbuf, fmt, aq);
}
+ else
+ strbuf->pos += (size_t)status;
- strbuf->pos += (size_t)status;
+ va_end(aq);
return (ssize_t)status;
} /* sdb_strbuf_vappend */