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();
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 @@ size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char>
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);
......
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