fix(demangle): limit ParseTemplateArg recursion depth (#963)
This commit is contained in:
parent
857df01007
commit
747b8a0774
@ -113,6 +113,7 @@ struct State {
|
|||||||
bool overflowed; // True if output gets overflowed.
|
bool overflowed; // True if output gets overflowed.
|
||||||
uint32 local_level;
|
uint32 local_level;
|
||||||
uint32 expr_level;
|
uint32 expr_level;
|
||||||
|
uint32 arg_level;
|
||||||
};
|
};
|
||||||
|
|
||||||
// We don't use strlen() in libc since it's not guaranteed to be async
|
// We don't use strlen() in libc since it's not guaranteed to be async
|
||||||
@ -159,6 +160,7 @@ static void InitState(State *state, const char *mangled,
|
|||||||
state->overflowed = false;
|
state->overflowed = false;
|
||||||
state->local_level = 0;
|
state->local_level = 0;
|
||||||
state->expr_level = 0;
|
state->expr_level = 0;
|
||||||
|
state->arg_level = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true and advances "mangled_cur" if we find "one_char_token"
|
// Returns true and advances "mangled_cur" if we find "one_char_token"
|
||||||
@ -1095,22 +1097,33 @@ static bool ParseTemplateArgs(State *state) {
|
|||||||
// ::= J <template-arg>* E # argument pack
|
// ::= J <template-arg>* E # argument pack
|
||||||
// ::= X <expression> E
|
// ::= X <expression> E
|
||||||
static bool ParseTemplateArg(State *state) {
|
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;
|
State copy = *state;
|
||||||
if ((ParseOneCharToken(state, 'I') || ParseOneCharToken(state, 'J')) &&
|
if ((ParseOneCharToken(state, 'I') || ParseOneCharToken(state, 'J')) &&
|
||||||
ZeroOrMore(ParseTemplateArg, state) &&
|
ZeroOrMore(ParseTemplateArg, state) &&
|
||||||
ParseOneCharToken(state, 'E')) {
|
ParseOneCharToken(state, 'E')) {
|
||||||
|
--state->arg_level;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
*state = copy;
|
*state = copy;
|
||||||
|
|
||||||
if (ParseType(state) ||
|
if (ParseType(state) ||
|
||||||
ParseExprPrimary(state)) {
|
ParseExprPrimary(state)) {
|
||||||
|
--state->arg_level;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
*state = copy;
|
*state = copy;
|
||||||
|
|
||||||
if (ParseOneCharToken(state, 'X') && ParseExpression(state) &&
|
if (ParseOneCharToken(state, 'X') && ParseExpression(state) &&
|
||||||
ParseOneCharToken(state, 'E')) {
|
ParseOneCharToken(state, 'E')) {
|
||||||
|
--state->arg_level;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
*state = copy;
|
*state = copy;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user