Commit a8ccb95b by Corentin Wallez Committed by Commit Bot

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/421271Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Corentin Wallez <cwallez@chromium.org>
parent 95401dbb
...@@ -19,8 +19,15 @@ const uintptr_t DirtyPointer = std::numeric_limits<uintptr_t>::max(); ...@@ -19,8 +19,15 @@ const uintptr_t DirtyPointer = std::numeric_limits<uintptr_t>::max();
size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char>& outBuffer) 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 // 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()) if (len < 0 || static_cast<size_t>(len) >= outBuffer.size())
{ {
// Buffer was not large enough, calculate the required size and resize the buffer // Buffer was not large enough, calculate the required size and resize the buffer
...@@ -28,7 +35,9 @@ size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char> ...@@ -28,7 +35,9 @@ size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char>
outBuffer.resize(len + 1); outBuffer.resize(len + 1);
// Print again // 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); ASSERT(len >= 0);
return static_cast<size_t>(len); return static_cast<size_t>(len);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment