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);