Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information...
commit a9bfbc5b698103b1553e1023c4f77001cc861e79 1 parent 26db0f2
Jeff King authored December 12, 2011 gitster committed December 12, 2011

Showing 1 changed file with 7 additions and 2 deletions. Show diff stats Hide diff stats

  1. 9  compat/snprintf.c
9  compat/snprintf.c
@@ -19,11 +19,14 @@
19 19
 #undef vsnprintf
20 20
 int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap)
21 21
 {
  22
+	va_list cp;
22 23
 	char *s;
23 24
 	int ret = -1;
24 25
 
25 26
 	if (maxsize > 0) {
26  
-		ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap);
  27
+		va_copy(cp, ap);
  28
+		ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, cp);
  29
+		va_end(cp);
27 30
 		if (ret == maxsize-1)
28 31
 			ret = -1;
29 32
 		/* 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)
42 45
 		if (! str)
43 46
 			break;
44 47
 		s = str;
45  
-		ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap);
  48
+		va_copy(cp, ap);
  49
+		ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, cp);
  50
+		va_end(cp);
46 51
 		if (ret == maxsize-1)
47 52
 			ret = -1;
48 53
 	}

0 notes on commit a9bfbc5

Please sign in to comment.
Something went wrong with that request. Please try again.