FYI: all tests passed on IRIX (not that I suspected otherwise). -Brandon On 12/12/2011 08:25 AM, Jeff King wrote: > 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; > } -- 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