summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: bcf4976)
raw | patch | inline | side by side (parent: bcf4976)
author | Sebastian Harl <sh@tokkee.org> | |
Wed, 20 Mar 2013 06:30:43 +0000 (23:30 -0700) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Wed, 20 Mar 2013 06:30:43 +0000 (23:30 -0700) |
After a va_list has been passed to a function that uses va_arg(), the value of
the va_list is undefined. Thus, rather copy the list before using it for the
first time to make sure we've got a valid va_list object on the second usage.
the va_list is undefined. Thus, rather copy the list before using it for the
first time to make sure we've got a valid va_list object on the second usage.
src/utils/strbuf.c | patch | blob | history |
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 */