Commit 2f61aed1 by Chris Mihelich Committed by Copybara-Service

Demangle sr St <simple-id> <simple-id>, a dubious encoding found in the wild.

PiperOrigin-RevId: 641418373
Change-Id: I2999228cccfd18a000725b938a692c0c9004867c
parent 696b3278
...@@ -2034,6 +2034,13 @@ static bool ParseBaseUnresolvedName(State *state) { ...@@ -2034,6 +2034,13 @@ static bool ParseBaseUnresolvedName(State *state) {
// <base-unresolved-name> // <base-unresolved-name>
// ::= [gs] sr <unresolved-qualifier-level>+ E // ::= [gs] sr <unresolved-qualifier-level>+ E
// <base-unresolved-name> // <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) { static bool ParseUnresolvedName(State *state) {
ComplexityGuard guard(state); ComplexityGuard guard(state);
if (guard.IsTooComplex()) return false; if (guard.IsTooComplex()) return false;
...@@ -2067,6 +2074,12 @@ static bool ParseUnresolvedName(State *state) { ...@@ -2067,6 +2074,12 @@ static bool ParseUnresolvedName(State *state) {
} }
state->parse_state = copy; state->parse_state = copy;
if (ParseTwoCharToken(state, "sr") && ParseTwoCharToken(state, "St") &&
ParseSimpleId(state) && ParseSimpleId(state)) {
return true;
}
state->parse_state = copy;
return false; return false;
} }
......
...@@ -1845,6 +1845,35 @@ TEST(Demangle, ThreadLocalWrappers) { ...@@ -1845,6 +1845,35 @@ TEST(Demangle, ThreadLocalWrappers) {
EXPECT_STREQ("thread-local initialization routine for ns::var", tmp); 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 // Test one Rust symbol to exercise Demangle's delegation path. Rust demangling
// itself is more thoroughly tested in demangle_rust_test.cc. // itself is more thoroughly tested in demangle_rust_test.cc.
TEST(Demangle, DelegatesToDemangleRustSymbolEncoding) { TEST(Demangle, DelegatesToDemangleRustSymbolEncoding) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment