diff options
author | Chris Mihelich <cmihelic@google.com> | 2024-06-07 19:20:24 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2024-06-07 19:21:12 -0700 |
commit | 2f61aed18c4affd3a75a2b2d2468d23f2f16192a (patch) | |
tree | 193c30224ce971b2bde3c8385d24c91811d38b53 | |
parent | 696b32788ca887881547380530926314c521ea7d (diff) | |
download | abseil-2f61aed18c4affd3a75a2b2d2468d23f2f16192a.tar.gz abseil-2f61aed18c4affd3a75a2b2d2468d23f2f16192a.tar.bz2 abseil-2f61aed18c4affd3a75a2b2d2468d23f2f16192a.zip |
Demangle sr St <simple-id> <simple-id>, a dubious encoding found in the wild.
PiperOrigin-RevId: 641418373
Change-Id: I2999228cccfd18a000725b938a692c0c9004867c
-rw-r--r-- | absl/debugging/internal/demangle.cc | 13 | ||||
-rw-r--r-- | absl/debugging/internal/demangle_test.cc | 29 |
2 files changed, 42 insertions, 0 deletions
diff --git a/absl/debugging/internal/demangle.cc b/absl/debugging/internal/demangle.cc index d97dfad4..f9dff5d8 100644 --- a/absl/debugging/internal/demangle.cc +++ b/absl/debugging/internal/demangle.cc @@ -2034,6 +2034,13 @@ static bool ParseBaseUnresolvedName(State *state) { // <base-unresolved-name> // ::= [gs] sr <unresolved-qualifier-level>+ E // <base-unresolved-name> +// ::= sr St <simple-id> <simple-id> # nonstandard +// +// The last case is not part of the official grammar but has been observed in +// real-world examples that the GNU demangler (but not the LLVM demangler) is +// able to decode; see demangle_test.cc for one such symbol name. The shape +// sr St <simple-id> <simple-id> was inferred by closed-box testing of the GNU +// demangler. static bool ParseUnresolvedName(State *state) { ComplexityGuard guard(state); if (guard.IsTooComplex()) return false; @@ -2067,6 +2074,12 @@ static bool ParseUnresolvedName(State *state) { } state->parse_state = copy; + if (ParseTwoCharToken(state, "sr") && ParseTwoCharToken(state, "St") && + ParseSimpleId(state) && ParseSimpleId(state)) { + return true; + } + state->parse_state = copy; + return false; } diff --git a/absl/debugging/internal/demangle_test.cc b/absl/debugging/internal/demangle_test.cc index 1b305f74..68a759c1 100644 --- a/absl/debugging/internal/demangle_test.cc +++ b/absl/debugging/internal/demangle_test.cc @@ -1845,6 +1845,35 @@ TEST(Demangle, ThreadLocalWrappers) { EXPECT_STREQ("thread-local initialization routine for ns::var", tmp); } +TEST(Demangle, DubiousSrStSymbols) { + char tmp[80]; + + // GNU demangling (not accepted by LLVM): + // + // S<std::u<char>::v> f<char>() + EXPECT_TRUE(Demangle("_Z1fIcE1SIXsrSt1uIT_E1vEEv", tmp, sizeof(tmp))); + EXPECT_STREQ("f<>()", tmp); + + // A real case from the wild. + // + // GNU demangling (not accepted by LLVM) with line breaks and indentation + // added for readability: + // + // __gnu_cxx::__enable_if<std::__is_char<char>::__value, bool>::__type + // std::operator==<char>( + // std::__cxx11::basic_string<char, std::char_traits<char>, + // std::allocator<char> > const&, + // std::__cxx11::basic_string<char, std::char_traits<char>, + // std::allocator<char> > const&) + EXPECT_TRUE(Demangle( + "_ZSteqIcEN9__gnu_cxx11__enable_if" + "IXsrSt9__is_charIT_E7__valueEbE" + "6__typeE" + "RKNSt7__cxx1112basic_stringIS3_St11char_traitsIS3_ESaIS3_EEESE_", + tmp, sizeof(tmp))); + EXPECT_STREQ("std::operator==<>()", tmp); +} + // Test one Rust symbol to exercise Demangle's delegation path. Rust demangling // itself is more thoroughly tested in demangle_rust_test.cc. TEST(Demangle, DelegatesToDemangleRustSymbolEncoding) { |