From eab1edb6763a22be52d1caf34330f30da57f287c Mon Sep 17 00:00:00 2001 From: Sergiu Deitsch Date: Fri, 6 Oct 2023 01:48:42 +0200 Subject: [PATCH] fix(demangle): limit recursion depth --- src/demangle.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/demangle.cc b/src/demangle.cc index 090ac570c..0c03a9e46 100644 --- a/src/demangle.cc +++ b/src/demangle.cc @@ -111,6 +111,7 @@ struct State { short nest_level; // For nested names. bool append; // Append flag. bool overflowed; // True if output gets overflowed. + uint32 local_level; }; // We don't use strlen() in libc since it's not guaranteed to be async @@ -155,6 +156,7 @@ static void InitState(State *state, const char *mangled, state->nest_level = -1; state->append = true; state->overflowed = false; + state->local_level = 0; } // Returns true and advances "mangled_cur" if we find "one_char_token" @@ -1208,16 +1210,25 @@ static bool ParseExprPrimary(State *state) { // [] // := Z <(function) encoding> E s [] static bool ParseLocalName(State *state) { + // Avoid recursion above max_levels + constexpr uint32 max_levels = 5; + if (state->local_level > max_levels) { + return false; + } + ++state->local_level; + State copy = *state; if (ParseOneCharToken(state, 'Z') && ParseEncoding(state) && ParseOneCharToken(state, 'E') && MaybeAppend(state, "::") && ParseName(state) && Optional(ParseDiscriminator(state))) { + --state->local_level; return true; } *state = copy; if (ParseOneCharToken(state, 'Z') && ParseEncoding(state) && ParseTwoCharToken(state, "Es") && Optional(ParseDiscriminator(state))) { + --state->local_level; return true; } *state = copy;