From fff9d11be528ad8f581cc7223b879c55009d7396 Mon Sep 17 00:00:00 2001 From: Fengwei Yin Date: Thu, 27 Feb 2014 01:17:09 +0800 Subject: [PATCH] Fix undefined args access for x86_64. From libc manual for vsnprintf: The functions vprintf(), vfprintf(), vsprintf(), vsnprintf() are equivalent to the functions printf(), fprintf(), sprintf(), snprintf(), respectively, except that they are called with a va_list instead of a variable number of arguments. These functions do not call the va_end macro. Because they invoke the va_arg macro, the value of ap is undefined after the call. We need to allocate/end new va_list for each vsnprintf. Change-Id: I66ec058033be1cb918e7b2bc84ca546800da226b Signed-off-by: Fengwei Yin --- libutils/String8.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/libutils/String8.cpp b/libutils/String8.cpp index e852d77b7..8acb4d45f 100644 --- a/libutils/String8.cpp +++ b/libutils/String8.cpp @@ -323,8 +323,17 @@ status_t String8::appendFormat(const char* fmt, ...) status_t String8::appendFormatV(const char* fmt, va_list args) { - int result = NO_ERROR; - int n = vsnprintf(NULL, 0, fmt, args); + int n, result = NO_ERROR; + va_list tmp_args; + + /* args is undefined after vsnprintf. + * So we need a copy here to avoid the + * second vsnprintf access undefined args. + */ + va_copy(tmp_args, args); + n = vsnprintf(NULL, 0, fmt, tmp_args); + va_end(tmp_args); + if (n != 0) { size_t oldLength = length(); char* buf = lockBuffer(oldLength + n);