From 2fe8a07c232b44de7e4b885dde631d8298e75c29 Mon Sep 17 00:00:00 2001 From: Zoltan Martonka Date: Mon, 28 Oct 2024 11:21:03 +0100 Subject: [PATCH] Fix null terminator in Demangle function. If the demangled name is longer than out_size, the null terminator is missing from the output. This will cause a crash in the DemangleInplace() function (symbolize.cc) when calling strlen on the buffer. --- src/demangle.cc | 3 +++ src/symbolize_unittest.cc | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/demangle.cc b/src/demangle.cc index 9902c1e10..43d935c8a 100644 --- a/src/demangle.cc +++ b/src/demangle.cc @@ -1351,6 +1351,9 @@ bool Demangle(const char* mangled, char* out, size_t out_size) { } std::copy_n(unmangled.get(), std::min(n, out_size), out); + if(n > out_size) { + out[out_size-1] = '\0'; + } return status == 0; #else State state; diff --git a/src/symbolize_unittest.cc b/src/symbolize_unittest.cc index f07484e63..8378ded30 100644 --- a/src/symbolize_unittest.cc +++ b/src/symbolize_unittest.cc @@ -35,6 +35,9 @@ #include #include +#include +#include + #include "config.h" #include "glog/logging.h" @@ -133,6 +136,18 @@ TEST(Symbolize, Symbolize) { struct Foo { static void func(int x); + static void longParamFunc( + std::map,std::map > p0, + std::map,std::map > p1, + std::map,std::map > p2, + std::map,std::map > p3, + std::map,std::map > p4, + std::map,std::map > p5, + std::map,std::map > p6, + std::map,std::map > p7, + std::map,std::map > p8, + std::map,std::map > p9 + ); }; void ATTRIBUTE_NOINLINE Foo::func(int x) { @@ -142,6 +157,22 @@ void ATTRIBUTE_NOINLINE Foo::func(int x) { a = a + 1; } +void ATTRIBUTE_NOINLINE Foo::longParamFunc( + std::map,std::map > p0, + std::map,std::map > p1, + std::map,std::map > p2, + std::map,std::map > p3, + std::map,std::map > p4, + std::map,std::map > p5, + std::map,std::map > p6, + std::map,std::map > p7, + std::map,std::map > p8, + std::map,std::map > p9 + ) { + volatile auto a = p0.size() + p1.size() + p2.size() + p3.size() + p4.size() + p5.size() + p6.size() + p7.size() + p8.size() + p9.size(); + a = a + 1; +} + // With a modern GCC, Symbolize() should return demangled symbol // names. Function parameters should be omitted. # ifdef TEST_WITH_MODERN_GCC @@ -150,6 +181,9 @@ TEST(Symbolize, SymbolizeWithDemangling) { # if !defined(_MSC_VER) || !defined(NDEBUG) # if defined(HAVE___CXA_DEMANGLE) EXPECT_STREQ("Foo::func(int)", TrySymbolize((void*)(&Foo::func))); + // Very long functions can be truncated, but we should not crash or return null + // Also the result should start properly. + EXPECT_TRUE(0 == std::string( TrySymbolize( (void*)(&Foo::longParamFunc))).find("Foo::longParamFunc(")); # else EXPECT_STREQ("Foo::func()", TrySymbolize((void*)(&Foo::func))); # endif