From a1e9e335a3e0bb7ffd6409c446332bb917d75fc5 Mon Sep 17 00:00:00 2001 From: Stanislav Malishevskiy Date: Wed, 1 Nov 2023 14:42:50 +0300 Subject: [PATCH] Fix I89GYA [ArkTS] String concatenation with null throws NPE Description: Follow code cause a null pointer exception let src: string|null = null; let dst: string = "" + src; So, avoid call toString method from null. Issue: https://gitee.com/openharmony-sig/arkcompiler_ets_frontend/issues/I89GYA Test: https://gitee.com/openharmony/arkcompiler_runtime_core/commit/f922c9d745766b7e0854421d0a1eb03491aa26c6 Signed-off-by: Konstantin Kuznetsov Signed-off-by: Stanislav Malishevskiy --- ets2panda/compiler/core/ETSGen.cpp | 62 +++++++++++++++--------------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/ets2panda/compiler/core/ETSGen.cpp b/ets2panda/compiler/core/ETSGen.cpp index f529a204cc..7a01cdebcd 100644 --- a/ets2panda/compiler/core/ETSGen.cpp +++ b/ets2panda/compiler/core/ETSGen.cpp @@ -2286,41 +2286,39 @@ void ETSGen::StringBuilderAppend(const ir::AstNode *node, VReg builder) node->Compile(this); - switch (checker::ETSChecker::ETSType(GetAccumulatorType())) { - case checker::TypeFlag::ETS_BOOLEAN: { - signature = Signatures::BUILTIN_STRING_BUILDER_APPEND_BOOLEAN; - break; - } - case checker::TypeFlag::CHAR: { - signature = Signatures::BUILTIN_STRING_BUILDER_APPEND_CHAR; - break; - } - case checker::TypeFlag::SHORT: - case checker::TypeFlag::BYTE: - case checker::TypeFlag::INT: { - signature = Signatures::BUILTIN_STRING_BUILDER_APPEND_INT; - break; - } - case checker::TypeFlag::LONG: { - signature = Signatures::BUILTIN_STRING_BUILDER_APPEND_LONG; - break; - } - case checker::TypeFlag::FLOAT: { - signature = Signatures::BUILTIN_STRING_BUILDER_APPEND_FLOAT; - break; - } - case checker::TypeFlag::DOUBLE: { - signature = Signatures::BUILTIN_STRING_BUILDER_APPEND_DOUBLE; - break; - } - default: { - signature = Signatures::BUILTIN_STRING_BUILDER_APPEND_BUILTIN_STRING; - break; - } + std::unordered_map type_flag_to_signatures_map { + {checker::TypeFlag::ETS_BOOLEAN, Signatures::BUILTIN_STRING_BUILDER_APPEND_BOOLEAN}, + {checker::TypeFlag::CHAR, Signatures::BUILTIN_STRING_BUILDER_APPEND_CHAR}, + {checker::TypeFlag::SHORT, Signatures::BUILTIN_STRING_BUILDER_APPEND_INT}, + {checker::TypeFlag::BYTE, Signatures::BUILTIN_STRING_BUILDER_APPEND_INT}, + {checker::TypeFlag::INT, Signatures::BUILTIN_STRING_BUILDER_APPEND_INT}, + {checker::TypeFlag::LONG, Signatures::BUILTIN_STRING_BUILDER_APPEND_LONG}, + {checker::TypeFlag::FLOAT, Signatures::BUILTIN_STRING_BUILDER_APPEND_FLOAT}, + {checker::TypeFlag::DOUBLE, Signatures::BUILTIN_STRING_BUILDER_APPEND_DOUBLE}, + }; + + auto search = type_flag_to_signatures_map.find(checker::ETSChecker::ETSType(GetAccumulatorType())); + if (search != type_flag_to_signatures_map.end()) { + signature = search->second; + } else { + signature = Signatures::BUILTIN_STRING_BUILDER_APPEND_BUILTIN_STRING; } if (GetAccumulatorType()->IsETSObjectType() && !GetAccumulatorType()->IsETSStringType()) { - Ra().Emit(node, Signatures::BUILTIN_OBJECT_TO_STRING, dummy_reg_, 0); + if (GetAccumulatorType()->ContainsNull() || GetAccumulatorType()->IsETSNullType()) { + Label *ifnull = AllocLabel(); + Label *end = AllocLabel(); + BranchIfNull(node, ifnull); + Ra().Emit(node, Signatures::BUILTIN_OBJECT_TO_STRING, dummy_reg_, 0); + JumpTo(node, end); + + SetLabel(node, ifnull); + LoadAccumulatorString(node, "null"); + + SetLabel(node, end); + } else { + Ra().Emit(node, Signatures::BUILTIN_OBJECT_TO_STRING, dummy_reg_, 0); + } } VReg arg0 = AllocReg(); -- Gitee