wgsl::ParserImpl: Use sync() for postfix_expr()

postfix_expr() handles `[]` array accessors and call expressions `()`.

Have postfix_expr() use sync to parse these:
* It will use the end bracket token to attempt to resynchronize the parser on error
* It also considers maximum parser recursion depth, avoiding stack overflows

Fixed: chromium:1180573
Change-Id: I8c1c62c68e24a564e0e4e7d0de9f5a3fa7032369
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/42222
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
Ben Clayton 2021-02-24 14:21:52 +00:00 committed by Commit Bot service account
parent 6d612ad478
commit 03eaff3b0a
1 changed files with 24 additions and 20 deletions

View File

@ -2136,34 +2136,38 @@ Maybe<ast::Expression*> ParserImpl::primary_expression() {
Maybe<ast::Expression*> ParserImpl::postfix_expr(ast::Expression* prefix) { Maybe<ast::Expression*> ParserImpl::postfix_expr(ast::Expression* prefix) {
Source source; Source source;
if (match(Token::Type::kBracketLeft, &source)) { if (match(Token::Type::kBracketLeft, &source)) {
auto param = logical_or_expression(); return sync(Token::Type::kBracketRight, [&]() -> Maybe<ast::Expression*> {
if (param.errored) auto param = logical_or_expression();
return Failure::kErrored; if (param.errored)
if (!param.matched) return Failure::kErrored;
return add_error(peek(), "unable to parse expression inside []"); if (!param.matched)
return add_error(peek(), "unable to parse expression inside []");
if (!expect("array accessor", Token::Type::kBracketRight)) if (!expect("array accessor", Token::Type::kBracketRight))
return Failure::kErrored; return Failure::kErrored;
return postfix_expr( return postfix_expr(
create<ast::ArrayAccessorExpression>(source, prefix, param.value)); create<ast::ArrayAccessorExpression>(source, prefix, param.value));
});
} }
if (match(Token::Type::kParenLeft, &source)) { if (match(Token::Type::kParenLeft, &source)) {
ast::ExpressionList params; return sync(Token::Type::kParenRight, [&]() -> Maybe<ast::Expression*> {
ast::ExpressionList params;
auto t = peek(); auto t = peek();
if (!t.IsParenRight() && !t.IsEof()) { if (!t.IsParenRight() && !t.IsEof()) {
auto list = expect_argument_expression_list(); auto list = expect_argument_expression_list();
if (list.errored) if (list.errored)
return Failure::kErrored;
params = list.value;
}
if (!expect("call expression", Token::Type::kParenRight))
return Failure::kErrored; return Failure::kErrored;
params = list.value;
}
if (!expect("call expression", Token::Type::kParenRight)) return postfix_expr(create<ast::CallExpression>(source, prefix, params));
return Failure::kErrored; });
return postfix_expr(create<ast::CallExpression>(source, prefix, params));
} }
if (match(Token::Type::kPeriod)) { if (match(Token::Type::kPeriod)) {