From c97c4dbeacec95ee6799126cb8cca721b71b7e8f Mon Sep 17 00:00:00 2001 From: Sandy Carter Date: Sun, 27 Jan 2019 10:10:04 -0500 Subject: [PATCH] [string] Remove reuse of va_list in AppendVarargs va_list are not guarenteed to maintain their values after being used. With clang on Linux, args is undefined after fetching length and will print "(null)". Copy args into another va_list before getting length to prevent this. Add tests. --- src/xenia/base/string_buffer.cc | 5 ++++- src/xenia/base/testing/string_test.cc | 13 +++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/xenia/base/string_buffer.cc b/src/xenia/base/string_buffer.cc index f7b4c8889..ac8a924d6 100644 --- a/src/xenia/base/string_buffer.cc +++ b/src/xenia/base/string_buffer.cc @@ -64,7 +64,10 @@ void StringBuffer::AppendFormat(const char* format, ...) { } void StringBuffer::AppendVarargs(const char* format, va_list args) { - int length = vsnprintf(nullptr, 0, format, args); + va_list size_args; + va_copy(size_args, args); // arg is indeterminate after the return so copy it + int length = vsnprintf(nullptr, 0, format, size_args); + va_end(size_args); Grow(length + 1); vsnprintf(buffer_ + buffer_offset_, buffer_capacity_, format, args); buffer_offset_ += length; diff --git a/src/xenia/base/testing/string_test.cc b/src/xenia/base/testing/string_test.cc index 1f287d933..946ed59b2 100644 --- a/src/xenia/base/testing/string_test.cc +++ b/src/xenia/base/testing/string_test.cc @@ -8,6 +8,7 @@ */ #include "xenia/base/string.h" +#include "xenia/base/string_buffer.h" #include "third_party/catch/include/catch.hpp" @@ -16,8 +17,16 @@ namespace base { namespace test { TEST_CASE("StringBuffer") { - // TODO(bwrsandman): - REQUIRE(false); + StringBuffer sb; + uint32_t module_flags = 0x1000000; + + std::string path_(R"(\Device\Cdrom0\default.xex)"); + sb.AppendFormat("Module %s:\n", path_.c_str()); + REQUIRE(sb.to_string() == "Module \\Device\\Cdrom0\\default.xex:\n"); + sb.AppendFormat(" Module Flags: %.8X\n", module_flags); + REQUIRE( + sb.to_string() == + "Module \\Device\\Cdrom0\\default.xex:\n Module Flags: 01000000\n"); } } // namespace test