Skip to content

Commit

Permalink
fix(demangle): limit ParseTemplateArg recursion depth (#963)
Browse files Browse the repository at this point in the history
  • Loading branch information
sergiud authored Oct 6, 2023
1 parent 857df01 commit 747b8a0
Showing 1 changed file with 13 additions and 0 deletions.
13 changes: 13 additions & 0 deletions src/demangle.cc
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ struct State {
bool overflowed; // True if output gets overflowed.
uint32 local_level;
uint32 expr_level;
uint32 arg_level;
};

// We don't use strlen() in libc since it's not guaranteed to be async
Expand Down Expand Up @@ -159,6 +160,7 @@ static void InitState(State *state, const char *mangled,
state->overflowed = false;
state->local_level = 0;
state->expr_level = 0;
state->arg_level = 0;
}

// Returns true and advances "mangled_cur" if we find "one_char_token"
Expand Down Expand Up @@ -1095,22 +1097,33 @@ static bool ParseTemplateArgs(State *state) {
// ::= J <template-arg>* E # argument pack
// ::= X <expression> E
static bool ParseTemplateArg(State *state) {
// Avoid recursion above max_levels
constexpr uint32 max_levels = 5;

if (state->arg_level > max_levels) {
return false;
}
++state->arg_level;

State copy = *state;
if ((ParseOneCharToken(state, 'I') || ParseOneCharToken(state, 'J')) &&
ZeroOrMore(ParseTemplateArg, state) &&
ParseOneCharToken(state, 'E')) {
--state->arg_level;
return true;
}
*state = copy;

if (ParseType(state) ||
ParseExprPrimary(state)) {
--state->arg_level;
return true;
}
*state = copy;

if (ParseOneCharToken(state, 'X') && ParseExpression(state) &&
ParseOneCharToken(state, 'E')) {
--state->arg_level;
return true;
}
*state = copy;
Expand Down

0 comments on commit 747b8a0

Please sign in to comment.