diff --git a/llvm/lib/Demangle/RustDemangle.cpp b/llvm/lib/Demangle/RustDemangle.cpp --- a/llvm/lib/Demangle/RustDemangle.cpp +++ b/llvm/lib/Demangle/RustDemangle.cpp @@ -438,8 +438,13 @@ // | "D" // dyn Trait + Send + 'a // | // backref void Demangler::demangleType() { - size_t Start = Position; + if (Error || RecursionLevel >= MaxRecursionLevel) { + Error = true; + return; + } + SwapAndRestore SaveRecursionLevel(RecursionLevel, RecursionLevel + 1); + size_t Start = Position; char C = consume(); BasicType Type; if (parseBasicType(C, Type)) @@ -506,6 +511,9 @@ Error = true; } break; + case 'B': + demangleBackref([&] { demangleType(); }); + break; default: Position = Start; demanglePath(rust_demangle::InType::Yes); diff --git a/llvm/test/Demangle/rust.test b/llvm/test/Demangle/rust.test --- a/llvm/test/Demangle/rust.test +++ b/llvm/test/Demangle/rust.test @@ -425,6 +425,9 @@ CHECK: backref:: _RIC7backrefNvB0_5identE +CHECK: backref::<(), ()> + _RIC7backrefuB9_E + ; Invalid backreferences CHECK: _RB_ @@ -436,6 +439,9 @@ CHECK: _RNvB_1a _RNvB_1a +CHECK: _RIC7backrefSB9_E + _RIC7backrefSB9_E + ; Invalid mangled characters CHECK: _RNvC2a.1c