diff --git a/ets2panda/checker/ets/arithmetic.cpp b/ets2panda/checker/ets/arithmetic.cpp index 3f7cdeda3dd594030a6fbb7f561c4321ae04f191..ba3f03fd87154c9402bbe4f229d5bd1af9fd435f 100644 --- a/ets2panda/checker/ets/arithmetic.cpp +++ b/ets2panda/checker/ets/arithmetic.cpp @@ -933,6 +933,10 @@ Type *ETSChecker::CheckBinaryOperatorNullishCoalescing(ir::Expression *left, ir: LogError(diagnostic::COALESCE_NOT_REF, {}, pos); } leftType = GetNonNullishType(leftType); + if (leftType->IsTypeError()) { + ES2PANDA_ASSERT(IsAnyError()); + return GlobalTypeError(); + } auto *rightType = MaybeBoxType(right->TsType()); if (IsTypeIdenticalTo(leftType, rightType)) { diff --git a/ets2panda/lexer/lexer.h b/ets2panda/lexer/lexer.h index 0725fc2d8f49ec7eb570ae7c3aa857bc655b3b64..47c03ba3d9d28a251ee8840da5965017c78df912 100644 --- a/ets2panda/lexer/lexer.h +++ b/ets2panda/lexer/lexer.h @@ -422,13 +422,14 @@ void Lexer::ScanString() PrepareStringTokenHelper(); const auto startPos = Iterator().Index(); auto escapeEnd = startPos; - bool validEscape = true; + bool isFinalizedStr = true; do { const char32_t cp = Iterator().Peek(); switch (cp) { case util::StringView::Iterator::INVALID_CP: { LogError(diagnostic::UNTERMINATED_STRING); + isFinalizedStr = false; break; } case LEX_CHAR_CR: @@ -441,7 +442,7 @@ void Lexer::ScanString() continue; } case LEX_CHAR_BACKSLASH: { - validEscape &= HandleBackslashHelper(&str, &escapeEnd); + isFinalizedStr &= HandleBackslashHelper(&str, &escapeEnd); continue; } case LEX_CHAR_BACK_TICK: @@ -464,7 +465,7 @@ void Lexer::ScanString() } } - FinalizeTokenHelper(&str, startPos, escapeEnd, validEscape); + FinalizeTokenHelper(&str, startPos, escapeEnd, isFinalizedStr); break; } while (true); diff --git a/ets2panda/parser/TypedParser.cpp b/ets2panda/parser/TypedParser.cpp index fa4c1f417adb30848f1bb4a3a994a178e4ed7184..268455be78070ccbc237e3940dc9c15e6b2cbaec 100644 --- a/ets2panda/parser/TypedParser.cpp +++ b/ets2panda/parser/TypedParser.cpp @@ -1256,6 +1256,9 @@ ir::Expression *TypedParser::ParseQualifiedReference(ir::Expression *typeName, E propName = AllocNode(Lexer()->GetToken().Ident(), Allocator()); } + if (propName == nullptr) { + return AllocBrokenExpression(Lexer()->GetToken().Loc()); + } propName->SetRange(Lexer()->GetToken().Loc()); typeName = AllocNode(typeName, propName, Allocator()); diff --git a/ets2panda/parser/statementParser.cpp b/ets2panda/parser/statementParser.cpp index 86f766bedcc0252c8688b7a7fe7be0a5365f29d7..27eb4e3c7adb015dd47eb83939da234a263caa0d 100644 --- a/ets2panda/parser/statementParser.cpp +++ b/ets2panda/parser/statementParser.cpp @@ -855,12 +855,16 @@ std::tuple if (condExpr->Alternate()->IsBinaryExpression() && condExpr->Alternate()->AsBinaryExpression()->OperatorType() == lexer::TokenType::KEYW_IN) { LogError(diagnostic::INVALID_LEFT_FOR_IN); + rightNode = AllocBrokenExpression(Lexer()->GetToken().Loc()); + updateNode = AllocBrokenExpression(Lexer()->GetToken().Loc()); // CC-OFFNXT(G.FMT.03-CPP) project code style return {ForStatementKind::IN, initNode, rightNode, updateNode}; } } if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { + rightNode = AllocBrokenExpression(Lexer()->GetToken().Loc()); + updateNode = AllocBrokenExpression(Lexer()->GetToken().Loc()); LogError(diagnostic::INVALID_LEFT_FOR_IN_OF); return {ForStatementKind::UPDATE, initNode, rightNode, updateNode}; } diff --git a/ets2panda/test/ast/compiler/ets/fuzzingtest0.ets b/ets2panda/test/ast/compiler/ets/fuzzingtest0.ets new file mode 100644 index 0000000000000000000000000000000000000000..63fb0322b11fe1da063d382c4195d76a4e7a4ca2 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/fuzzingtest0.ets @@ -0,0 +1,25 @@ +/* + * 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. + */ + +// the test case is from fuzzer. +let callback = () => {for /* @@ label1 */aa !== /* @@ label2 */arr[idx]/* @@ label3 */) + +/* @@@ label1 Error SyntaxError: Expected '(', got 'identification literal'. */ +/* @@@ label1 Error TypeError: Unresolved reference aa */ +/* @@@ label2 Error TypeError: Unresolved reference arr */ +/* @@@ label2 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@@ label3 Error SyntaxError: Invalid left-hand side in 'For[In/Of]Statement'. */ +/* @@? 26:1 Error SyntaxError: Unexpected token 'end of stream'. */ +/* @@? 26:1 Error SyntaxError: Expected '}', got 'end of stream'. */ diff --git a/ets2panda/test/ast/compiler/ets/fuzzingtest1.ets b/ets2panda/test/ast/compiler/ets/fuzzingtest1.ets new file mode 100644 index 0000000000000000000000000000000000000000..32a58853e998c5da757dd44aa0905a3cf9a08223 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/fuzzingtest1.ets @@ -0,0 +1,22 @@ +/* + * 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. + */ + +// the test case is from fuzzer. +/* @@ label */fuzzz./* @@ label2 */@@/* @@ label3 */@@ + +/* @@@ label Error TypeError: Unresolved reference fuzzz */ +/* @@@ label2 Error SyntaxError: There is no any node to insert at the placeholder position. */ +/* @@@ label2 Error SyntaxError: Identifier expected, got '@@'. */ +/* @@@ label3 Error SyntaxError: Unexpected token '@@'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/fuzzingtest2.ets b/ets2panda/test/ast/compiler/ets/fuzzingtest2.ets new file mode 100644 index 0000000000000000000000000000000000000000..eff6fa17ba130e470d740431c838955d1a41bd3f --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/fuzzingtest2.ets @@ -0,0 +1,20 @@ +/* + * 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. + */ + +// the test case is from fuzzer. +/* @@ label */i ??/* @@ label2 */@@ + +/* @@@ label Error TypeError: Unresolved reference i */ +/* @@@ label2 Error SyntaxError: Unexpected token '@@'. */ diff --git a/ets2panda/test/ast/compiler/ets/fuzzingtest3.ets b/ets2panda/test/ast/compiler/ets/fuzzingtest3.ets new file mode 100644 index 0000000000000000000000000000000000000000..f3b80f5accdf87cfe4c100707ab1fe084746f04b --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/fuzzingtest3.ets @@ -0,0 +1,24 @@ +/* + * 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. + */ + +// the test case is from fuzzer. +/* @@? 24:1 Error TypeError: Unresolved reference abcdefghijklmnopqrstuvwxyzABC */ +/* @@? 24:30 Error SyntaxError: Unexpected token '`'. */ +/* @@? 24:30 Error SyntaxError: Unexpected token, expected '`'. */ +/* @@? 24:31 Error SyntaxError: Unterminated string. */ +/* @@? 24:31 Error SyntaxError: Unexpected token, expected '${' or '`' */ +/* @@? 24:31 Error SyntaxError: Unexpected token, expected '`'. */ + +abcdefghijklmnopqrstuvwxyzABC`DEF\n� \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_56.ets b/ets2panda/test/ast/parser/ets/unexpected_token_56.ets index 556f4484e1776aca2f29c671170fc48615c8c4d5..e5954717ade1b9c60b6dfdfe8992adf2e7932bd5 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_56.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_56.ets @@ -13,22 +13,22 @@ * limitations under the License. */ -for await (/* @@ label1 */;/* @@ label2 */;i < count/* @@ label3 */; ++i/* @@ label */) { - result = result + p[i]!.awaitResolution() * a[i]; +for await (/* @@ label1 */;/* @@ label2 */;/* @@ label3 */i < /* @@ label4 */count/* @@ label5 */; ++i/* @@ label6 */) /* @@ label7 */{ + /* @@ label8 */result = result + /* @@ label9 */p[i]!.awaitResolution() * /* @@ label10 */a[i]; } -for (let i? : Number = 1;;) { break; } +for (let i? /* @@ label11 */: Number = 1;;) { break; } /* @@@ label1 Error SyntaxError: Unexpected token ';'. */ /* @@@ label2 Error SyntaxError: Unexpected token ';'. */ -/* @@? 16:44 Error TypeError: Unresolved reference i */ -/* @@? 16:44 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ -/* @@? 16:48 Error TypeError: Function name 'count' used in the wrong context */ -/* @@@ label3 Error SyntaxError: Expected ')', got ';'. */ -/* @@@ label Error SyntaxError: Unexpected token ')'. */ -/* @@? 16:89 Error SyntaxError: Unexpected token '{'. */ -/* @@? 17:5 Error TypeError: Unresolved reference result */ -/* @@? 17:23 Error TypeError: Unresolved reference p */ -/* @@? 17:23 Error TypeError: Indexed access is not supported for such expression type. */ -/* @@? 17:49 Error TypeError: Unresolved reference a */ -/* @@? 17:49 Error TypeError: Indexed access is not supported for such expression type. */ -/* @@? 19:13 Error SyntaxError: Optional variable is deprecated and no longer supported. */ +/* @@@ label3 Error TypeError: Unresolved reference i */ +/* @@@ label3 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ +/* @@@ label4 Error TypeError: Function name 'count' used in the wrong context */ +/* @@@ label5 Error SyntaxError: Expected ')', got ';'. */ +/* @@@ label6 Error SyntaxError: Unexpected token ')'. */ +/* @@@ label7 Error SyntaxError: Unexpected token '{'. */ +/* @@@ label8 Error TypeError: Unresolved reference result */ +/* @@@ label9 Error TypeError: Unresolved reference p */ +/* @@@ label9 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@@ label10 Error TypeError: Unresolved reference a */ +/* @@@ label10 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@@ label11 Error SyntaxError: Optional variable is deprecated and no longer supported. */