On Mon, Dec 12, 2011 at 10:30:27AM +0100, Andreas Schwab wrote: > Jeff King <peff@xxxxxxxx> writes: > > > if (maxsize > 0) { > > - ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap); > > + va_copy(cp, ap); > > + ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, cp); > > You also need to call va_end on the copy. Silly me. Thanks for catching. Junio, here's a corrected version. -- >8 -- Subject: [PATCH] compat/snprintf: don't look at va_list twice If you define SNPRINTF_RETURNS_BOGUS, we use a special git_vsnprintf wrapper assumes that vsnprintf returns "-1" instead of the number of characters that you would need to store the result. To do this, it invokes vsnprintf multiple times, growing a heap buffer until we have enough space to hold the result. However, this means we evaluate the va_list parameter multiple times, which is generally a bad thing (it may be modified by calls to vsnprintf, yielding undefined behavior). Instead, we must va_copy it and hand the copy to vsnprintf, so we always have a pristine va_list. Signed-off-by: Jeff King <peff@xxxxxxxx> --- compat/snprintf.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-) diff --git a/compat/snprintf.c b/compat/snprintf.c index e1e0e75..42ea1ac 100644 --- a/compat/snprintf.c +++ b/compat/snprintf.c @@ -19,11 +19,14 @@ #undef vsnprintf int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap) { + va_list cp; char *s; int ret = -1; if (maxsize > 0) { - ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap); + va_copy(cp, ap); + ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, cp); + va_end(cp); if (ret == maxsize-1) ret = -1; /* Windows does not NUL-terminate if result fills buffer */ @@ -42,7 +45,9 @@ int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap) if (! str) break; s = str; - ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap); + va_copy(cp, ap); + ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, cp); + va_end(cp); if (ret == maxsize-1) ret = -1; } -- 1.7.8.13.g74677 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html