From 29c70796d390a6ee66699c2437e4eb1555ae8ffa Mon Sep 17 00:00:00 2001 From: Ben Clayton Date: Fri, 16 Jul 2021 17:55:14 +0000 Subject: [PATCH] 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 Kokoro: Kokoro Reviewed-by: David Neto Commit-Queue: Ben Clayton --- src/reader/wgsl/parser_impl.cc | 79 ++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 32 deletions(-) diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc index 1c8bfda35b..d8209a7b14 100644 --- a/src/reader/wgsl/parser_impl.cc +++ b/src/reader/wgsl/parser_impl.cc @@ -2224,42 +2224,57 @@ Maybe 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 { - 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(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( - ident.source, prefix, - create( - ident.source, builder_.Symbols().Register(ident.value)))); + if (match(Token::Type::kBracketLeft, &source)) { + auto res = + sync(Token::Type::kBracketRight, [&]() -> Maybe { + 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(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( + ident.source, prefix, + create( + ident.source, builder_.Symbols().Register(ident.value))); + continue; + } + + return prefix; } - return prefix; + return Failure::kErrored; } // singular_expression