FormatString: avoid an UB when we need to grow the buffer

A va_list is undefined after it has been used by vsnprtinf. This was
causing crashes in the GL backend when the driver was returning big
info logs.

BUG=chromium:668223

Change-Id: I444194ecce2846960c8a27f20f322f7099c651e5
Reviewed-on: https://chromium-review.googlesource.com/421271
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/common/angleutils.cpp b/src/common/angleutils.cpp
index 7099c21..05348a4 100644
--- a/src/common/angleutils.cpp
+++ b/src/common/angleutils.cpp
@@ -19,8 +19,15 @@
 
 size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char>& outBuffer)
 {
+    // The state of the va_list passed to vsnprintf is undefined after the call, do a copy in case
+    // we need to grow the buffer.
+    va_list varargCopy;
+    va_copy(varargCopy, vararg);
+
     // Attempt to just print to the current buffer
-    int len = vsnprintf(&(outBuffer.front()), outBuffer.size(), fmt, vararg);
+    int len = vsnprintf(&(outBuffer.front()), outBuffer.size(), fmt, varargCopy);
+    va_end(varargCopy);
+
     if (len < 0 || static_cast<size_t>(len) >= outBuffer.size())
     {
         // Buffer was not large enough, calculate the required size and resize the buffer
@@ -28,7 +35,9 @@
         outBuffer.resize(len + 1);
 
         // Print again
-        len = vsnprintf(&(outBuffer.front()), outBuffer.size(), fmt, vararg);
+        va_copy(varargCopy, vararg);
+        len = vsnprintf(&(outBuffer.front()), outBuffer.size(), fmt, varargCopy);
+        va_end(varargCopy);
     }
     ASSERT(len >= 0);
     return static_cast<size_t>(len);