From 3f3ee1d2cf15a2e3f2bff3885cc873c10d9db9fa Mon Sep 17 00:00:00 2001 From: daizihan Date: Fri, 11 Jul 2025 17:09:57 +0800 Subject: [PATCH] Fix fuzz crashes Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICLQFU?from=project-issue Signed-off-by: daizihan --- .../ir/statements/forUpdateStatement.cpp | 17 +++++++-- ets2panda/parser/ETSparser.h | 1 + ets2panda/parser/ETSparserExpressions.cpp | 38 +++++++++++++++++++ ets2panda/parser/parserImpl.h | 2 +- ...w_function_call_as_record_property_key.ets | 32 ++++++++++++++-- .../parser/ets/invalid_object_expression.ets | 28 ++++++++++++++ .../ast/parser/ets/unexpected_token_52.ets | 22 ++++++++--- .../ast/parser/ets/update_funcscope_error.ets | 9 +++++ ets2panda/test/runtime/ets/empty_for_init.ets | 35 +++++++++++++++++ 9 files changed, 171 insertions(+), 13 deletions(-) create mode 100644 ets2panda/test/ast/parser/ets/invalid_object_expression.ets create mode 100644 ets2panda/test/runtime/ets/empty_for_init.ets diff --git a/ets2panda/ir/statements/forUpdateStatement.cpp b/ets2panda/ir/statements/forUpdateStatement.cpp index 912dd11f40..cd0d2d5317 100644 --- a/ets2panda/ir/statements/forUpdateStatement.cpp +++ b/ets2panda/ir/statements/forUpdateStatement.cpp @@ -127,9 +127,20 @@ checker::VerifiedType ForUpdateStatement::Check(checker::ETSChecker *checker) ForUpdateStatement *ForUpdateStatement::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const init = init_->Clone(allocator, nullptr); - auto *const test = test_->Clone(allocator, nullptr)->AsExpression(); - auto *const update = update_->Clone(allocator, nullptr)->AsExpression(); + ir::AstNode *init = nullptr; + if (init_ != nullptr) { + init = init_->Clone(allocator, nullptr); + } + + ir::Expression *test = nullptr; + if (test_ != nullptr) { + test = test_->Clone(allocator, nullptr)->AsExpression(); + } + + ir::Expression *update = nullptr; + if (update_ != nullptr) { + update = update_->Clone(allocator, nullptr)->AsExpression(); + } auto *const body = body_->Clone(allocator, nullptr)->AsStatement(); auto *const clone = util::NodeAllocator::ForceSetParent(allocator, init, test, update, body); diff --git a/ets2panda/parser/ETSparser.h b/ets2panda/parser/ETSparser.h index 533d672e1f..918b3e15b5 100644 --- a/ets2panda/parser/ETSparser.h +++ b/ets2panda/parser/ETSparser.h @@ -318,6 +318,7 @@ private: ExpressionParseFlags flags = ExpressionParseFlags::NO_OPTS) override; // NOLINTNEXTLINE(google-default-arguments) ir::Expression *ParsePropertyDefinition(ExpressionParseFlags flags = ExpressionParseFlags::NO_OPTS) override; + ir::Expression *ParsePropertyKey(ExpressionParseFlags flags) override; // NOLINTNEXTLINE(google-default-arguments) ir::Expression *ParseDefaultPrimaryExpression(ExpressionParseFlags flags = ExpressionParseFlags::NO_OPTS); // NOLINTNEXTLINE(google-default-arguments) diff --git a/ets2panda/parser/ETSparserExpressions.cpp b/ets2panda/parser/ETSparserExpressions.cpp index 3ea3834860..c1122b3436 100644 --- a/ets2panda/parser/ETSparserExpressions.cpp +++ b/ets2panda/parser/ETSparserExpressions.cpp @@ -238,6 +238,44 @@ bool CheckNextTokenOfTypeof(const lexer::Token &token) return (pretendTypeof || pretendIdent || pretendOperator || pretendUnary || pretendPuctuator); } +ir::Expression *ETSParser::ParsePropertyKey([[maybe_unused]] ExpressionParseFlags flags) +{ + ir::Expression *key = nullptr; + + switch (Lexer()->GetToken().Type()) { + case lexer::TokenType::LITERAL_IDENT: { + const util::StringView &ident = Lexer()->GetToken().Ident(); + key = AllocNode(ident, Allocator()); + key->SetRange(Lexer()->GetToken().Loc()); + Lexer()->NextToken(); + return key; + } + case lexer::TokenType::LITERAL_STRING: { + const util::StringView &string = Lexer()->GetToken().String(); + key = AllocNode(string); + key->SetRange(Lexer()->GetToken().Loc()); + Lexer()->NextToken(); + return key; + } + case lexer::TokenType::LITERAL_NUMBER: { + if ((Lexer()->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) != 0) { + key = AllocNode(Lexer()->GetToken().BigInt()); + } else { + key = AllocNode(Lexer()->GetToken().GetNumber()); + } + key->SetRange(Lexer()->GetToken().Loc()); + Lexer()->NextToken(); + return key; + } + default: { + const auto &rangeToken = Lexer()->GetToken().Loc(); + LogError(diagnostic::UNEXPECTED_TOKEN); + Lexer()->NextToken(); + return AllocBrokenExpression(rangeToken); + } + } +} + // NOLINTNEXTLINE(google-default-arguments) ir::Expression *ETSParser::ParseDefaultPrimaryExpression(ExpressionParseFlags flags) { diff --git a/ets2panda/parser/parserImpl.h b/ets2panda/parser/parserImpl.h index 6417c818c0..77436ed8be 100644 --- a/ets2panda/parser/parserImpl.h +++ b/ets2panda/parser/parserImpl.h @@ -151,7 +151,7 @@ protected: void ValidateGroupedExpression(ir::Expression *lhsExpression); ir::Expression *ParseImportExpression(); ir::Expression *ParseOptionalChain(ir::Expression *leftSideExpr); - ir::Expression *ParsePropertyKey(ExpressionParseFlags flags); + virtual ir::Expression *ParsePropertyKey(ExpressionParseFlags flags); void ValidateAssignmentTarget(ExpressionParseFlags flags, ir::Expression *node); void ValidateLvalueAssignmentTarget(ir::Expression *node); void ValidateArrowParameterBindings(const ir::Expression *node); diff --git a/ets2panda/test/ast/compiler/ets/arrow_function_call_as_record_property_key.ets b/ets2panda/test/ast/compiler/ets/arrow_function_call_as_record_property_key.ets index b989234f62..b19f92968c 100644 --- a/ets2panda/test/ast/compiler/ets/arrow_function_call_as_record_property_key.ets +++ b/ets2panda/test/ast/compiler/ets/arrow_function_call_as_record_property_key.ets @@ -24,6 +24,32 @@ const b: Record number> = { [(():number => +("bar"))()]: (y: string):number => y.length }; -/* @@? 21:21 Error TypeError: Bad operand type, the type of the operand must be numeric type. */ -/* @@? 21:34 Error SyntaxError: Function expressions are not supported, use arrow functions instead */ -/* @@? 24:21 Error TypeError: Bad operand type, the type of the operand must be numeric type. */ +/* @@? 16:35 Error TypeError: need to specify target type for class composite */ +/* @@? 17:5 Error SyntaxError: Unexpected token. */ +/* @@? 17:6 Error SyntaxError: Unexpected token, expected ':'. */ +/* @@? 17:22 Error SyntaxError: Unexpected token. */ +/* @@? 17:25 Error SyntaxError: Unexpected token ']'. */ +/* @@? 17:26 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:28 Error SyntaxError: Unexpected token '1'. */ +/* @@? 18:1 Error SyntaxError: Unexpected token '}'. */ +/* @@? 20:50 Error TypeError: need to specify target type for class composite */ +/* @@? 21:5 Error SyntaxError: Unexpected token. */ +/* @@? 21:6 Error SyntaxError: Unexpected token, expected ':'. */ +/* @@? 21:28 Error SyntaxError: Unexpected token. */ +/* @@? 21:31 Error SyntaxError: Unexpected token ']'. */ +/* @@? 21:32 Error SyntaxError: Unexpected token ':'. */ +/* @@? 21:34 Error SyntaxError: Unexpected token 'function'. */ +/* @@? 21:43 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 23:6 Error SyntaxError: Unexpected token ','. */ +/* @@? 23:6 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 24:32 Error SyntaxError: Unexpected token ':'. */ +/* @@? 24:35 Error TypeError: Unresolved reference y */ +/* @@? 24:36 Error SyntaxError: Unexpected token ':'. */ +/* @@? 24:36 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 24:38 Error SyntaxError: Unexpected token 'string'. */ +/* @@? 24:38 Error TypeError: Type name 'string' used in the wrong context */ +/* @@? 24:44 Error SyntaxError: Unexpected token ')'. */ +/* @@? 24:45 Error SyntaxError: Unexpected token ':'. */ +/* @@? 24:46 Error SyntaxError: Unexpected token 'number'. */ +/* @@? 24:46 Error TypeError: The type of parameter 'number' cannot be inferred */ +/* @@? 25:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/parser/ets/invalid_object_expression.ets b/ets2panda/test/ast/parser/ets/invalid_object_expression.ets new file mode 100644 index 0000000000..a7b52b8558 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/invalid_object_expression.ets @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +let obj: Record = { + [this.viewModel.ads] : 123 +} + +/* @@? 18:5 Error SyntaxError: Unexpected token. */ +/* @@? 18:6 Error SyntaxError: Unexpected token. */ +/* @@? 18:6 Error TypeError: Cannot reference 'this' in this context. */ +/* @@? 18:11 Error TypeError: Property 'viewModel' does not exist on type 'Error' */ +/* @@? 18:24 Error SyntaxError: Unexpected token. */ +/* @@? 18:26 Error SyntaxError: Unexpected token ':'. */ +/* @@? 18:28 Error SyntaxError: Unexpected token '123'. */ +/* @@? 19:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_52.ets b/ets2panda/test/ast/parser/ets/unexpected_token_52.ets index b447ab92d5..9b65b55ca6 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_52.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_52.ets @@ -13,11 +13,21 @@ * limitations under the License. */ -let /* @@ label1 */a = { - get [/* @@ label2 */b/* @@ label3 */)(){}, - ...a, +let a = { + get [b)(){}, + ...a, } -/* @@@ label1 Error TypeError: Cannot infer type for a because class composite needs an explicit target type */ -/* @@@ label2 Error SyntaxError: Object pattern can't contain methods. */ -/* @@@ label3 Error SyntaxError: Unexpected token, expected ']'. */ +/* @@? 16:5 Error TypeError: Cannot infer type for a because class composite needs an explicit target type */ +/* @@? 17:9 Error SyntaxError: Unexpected token. */ +/* @@? 17:10 Error SyntaxError: Unexpected token, expected '('. */ +/* @@? 17:10 Error SyntaxError: Object pattern can't contain methods. */ +/* @@? 17:12 Error SyntaxError: Expected '{', got '('. */ +/* @@? 17:12 Error SyntaxError: Unexpected token. */ +/* @@? 17:13 Error SyntaxError: Unexpected token ')'. */ +/* @@? 17:14 Error SyntaxError: Unexpected token '{'. */ +/* @@? 17:16 Error SyntaxError: Unexpected token ','. */ +/* @@? 18:5 Error SyntaxError: Unexpected token '...'. */ +/* @@? 18:8 Error SyntaxError: Unexpected token 'a'. */ +/* @@? 18:9 Error SyntaxError: Unexpected token ','. */ +/* @@? 19:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/parser/ets/update_funcscope_error.ets b/ets2panda/test/ast/parser/ets/update_funcscope_error.ets index 5d2ca8cb59..a14e53cb62 100644 --- a/ets2panda/test/ast/parser/ets/update_funcscope_error.ets +++ b/ets2panda/test/ast/parser/ets/update_funcscope_error.ets @@ -38,4 +38,13 @@ export const updateIfChanged = (t: Record) => { /* @@? 21:19 Error TypeError: Indexed access is not supported for such expression type. */ /* @@? 24:7 Error TypeError: Type '(v: Record) => Boolean' is not compatible with type '(previousValue: Boolean, currentValue: Boolean, index: Double, array: FixedArray) => Boolean' at index 2 */ /* @@? 27:11 Error SyntaxError: Property or signature expected. */ +/* @@? 28:11 Error SyntaxError: Unexpected token. */ +/* @@? 28:12 Error SyntaxError: Unexpected token. */ +/* @@? 28:15 Error SyntaxError: Unexpected token. */ +/* @@? 28:16 Error SyntaxError: Unexpected token ':'. */ +/* @@? 28:18 Error SyntaxError: Unexpected token 'v'. */ +/* @@? 29:10 Error SyntaxError: Unexpected token, expected ',' or ')'. */ /* @@? 30:16 Error TypeError: Unresolved reference update */ +/* @@? 32:5 Error SyntaxError: Unexpected token ')'. */ +/* @@? 33:12 Error TypeError: Unresolved reference reduceResult */ +/* @@? 35:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/runtime/ets/empty_for_init.ets b/ets2panda/test/runtime/ets/empty_for_init.ets new file mode 100644 index 0000000000..5875761b7d --- /dev/null +++ b/ets2panda/test/runtime/ets/empty_for_init.ets @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +let foo = (() => { + for (let i = 0; i < 1;) { + } +}) + +let foo1 = (() => { + let i = 0 + for (;; i++) { + } +}) + +let foo2 = (() => { + for (;;) { + } +}) + +function main() { + arktest.assertTrue(true); +} -- Gitee