parser/wgsl: Fix stack overflow in postfix_expression()

Have postfix_expression() use a loop instead of recursively calling itself.

Fixed chromium:1229669

Change-Id: Ied7684d00ba453a8b89ab0251d42e2a72169421f
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/58381
Auto-Submit: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: David Neto <dneto@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
Ben Clayton 2021-07-16 17:55:14 +00:00 committed by Tint LUCI CQ
parent fa4d4341f4
commit 29c70796d3

View File

@ -2224,42 +2224,57 @@ Maybe<ast::Expression*> ParserImpl::postfix_expression(
ast::Expression* prefix) {
Source source;
if (match(Token::Type::kPlusPlus, &source) ||
match(Token::Type::kMinusMinus, &source)) {
add_error(source,
"postfix increment and decrement operators are reserved for a "
"future WGSL version");
return Failure::kErrored;
}
if (match(Token::Type::kBracketLeft, &source)) {
return sync(Token::Type::kBracketRight, [&]() -> Maybe<ast::Expression*> {
auto param = logical_or_expression();
if (param.errored)
return Failure::kErrored;
if (!param.matched)
return add_error(peek(), "unable to parse expression inside []");
if (!expect("array accessor", Token::Type::kBracketRight))
return Failure::kErrored;
return postfix_expression(
create<ast::ArrayAccessorExpression>(source, prefix, param.value));
});
}
if (match(Token::Type::kPeriod)) {
auto ident = expect_ident("member accessor");
if (ident.errored)
while (continue_parsing()) {
if (match(Token::Type::kPlusPlus, &source) ||
match(Token::Type::kMinusMinus, &source)) {
add_error(source,
"postfix increment and decrement operators are reserved for a "
"future WGSL version");
return Failure::kErrored;
}
return postfix_expression(create<ast::MemberAccessorExpression>(
ident.source, prefix,
create<ast::IdentifierExpression>(
ident.source, builder_.Symbols().Register(ident.value))));
if (match(Token::Type::kBracketLeft, &source)) {
auto res =
sync(Token::Type::kBracketRight, [&]() -> Maybe<ast::Expression*> {
auto param = logical_or_expression();
if (param.errored)
return Failure::kErrored;
if (!param.matched) {
return add_error(peek(), "unable to parse expression inside []");
}
if (!expect("array accessor", Token::Type::kBracketRight)) {
return Failure::kErrored;
}
return create<ast::ArrayAccessorExpression>(source, prefix,
param.value);
});
if (res.errored) {
return res;
}
prefix = res.value;
continue;
}
if (match(Token::Type::kPeriod)) {
auto ident = expect_ident("member accessor");
if (ident.errored) {
return Failure::kErrored;
}
prefix = create<ast::MemberAccessorExpression>(
ident.source, prefix,
create<ast::IdentifierExpression>(
ident.source, builder_.Symbols().Register(ident.value)));
continue;
}
return prefix;
}
return prefix;
return Failure::kErrored;
}
// singular_expression