diff options
author | Fengwei Yin <fengwei.yin@intel.com> | 2014-02-27 01:17:09 +0800 |
---|---|---|
committer | Fengwei Yin <fengwei.yin@intel.com> | 2014-02-27 01:17:09 +0800 |
commit | fff9d11be528ad8f581cc7223b879c55009d7396 (patch) | |
tree | 9ca229a0254dcd2c76a3e4cb5721e410e5d3cb63 /libutils | |
parent | ebb46d76e4bf4ee4f34b42709ea69cce07e3e322 (diff) | |
download | system_core-fff9d11be528ad8f581cc7223b879c55009d7396.zip system_core-fff9d11be528ad8f581cc7223b879c55009d7396.tar.gz system_core-fff9d11be528ad8f581cc7223b879c55009d7396.tar.bz2 |
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 <fengwei.yin@intel.com>
Diffstat (limited to 'libutils')
-rw-r--r-- | libutils/String8.cpp | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/libutils/String8.cpp b/libutils/String8.cpp index e852d77..8acb4d4 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); |