* 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.
*/
#include "common_components/base/utf_helper.h"
#include "common_components/tests/test_helper.h"
using namespace common;
namespace common::test {
class UtfHelperTest : public common::test::BaseTestWithScope {
};
HWTEST_F_L0(UtfHelperTest, DecodeUTF16Test1)
{
uint16_t utf16[] = {0xD7FF};
size_t index = 0;
size_t len = 1;
uint32_t result = utf_helper::DecodeUTF16(utf16, len, &index, false);
EXPECT_EQ(result, 0xD7FF);
uint16_t utf16In[] = {0xDC00};
result = utf_helper::DecodeUTF16(utf16In, len, &index, false);
EXPECT_EQ(result, 0xDC00);
uint16_t utf16In1[] = {0xD800};
result = utf_helper::DecodeUTF16(utf16In1, len, &index, false);
EXPECT_EQ(result, 0xD800);
uint16_t utf16In2[] = {0xD7FF};
len = 2;
result = utf_helper::DecodeUTF16(utf16In2, len, &index, false);
EXPECT_EQ(result, 0xD7FF);
len = 1;
result = utf_helper::DecodeUTF16(utf16In2, len, &index, false);
EXPECT_EQ(result, 0xD7FF);
result = utf_helper::DecodeUTF16(utf16In, len, &index, false);
EXPECT_EQ(result, 0xDC00);
}
HWTEST_F_L0(UtfHelperTest, DecodeUTF16Test2)
{
size_t index = 0;
uint16_t utf16[] = {0xD800, 0xDC00};
size_t len = 2;
utf16[1] = 0xFFFF;
uint32_t result = utf_helper::DecodeUTF16(utf16, len, &index, false);
EXPECT_EQ(result, 0xD800);
}
HWTEST_F_L0(UtfHelperTest, DecodeUTF16Test3)
{
size_t index = 0;
uint16_t utf16[] = {0xD800, 0xDC00};
size_t len = 2;
uint32_t result = utf_helper::DecodeUTF16(utf16, len, &index, true);
EXPECT_EQ(result, 0xD800);
uint16_t utf16In[] = {0xD800, 0x0041};
result = utf_helper::DecodeUTF16(utf16In, len, &index, false);
EXPECT_EQ(result, 0xD800);
uint16_t utf16In1[] = {0xD800, 0xDC00};
index = 0;
len = 2;
result = utf_helper::DecodeUTF16(utf16In1, len, &index, false);
EXPECT_EQ(result, 0x10000);
uint16_t utf16In2[] = {0x0041, 0x0042};
index = 0;
len = 2;
result = utf_helper::DecodeUTF16(utf16In2, len, &index, false);
EXPECT_EQ(result, 0x0041);
}
HWTEST_F_L0(UtfHelperTest, HandleAndDecodeInvalidUTF16Test1)
{
uint16_t input[] = {0xDC00};
size_t index = 0;
size_t len = sizeof(input) / sizeof(input[0]);
uint32_t result = utf_helper::HandleAndDecodeInvalidUTF16(input, len, &index);
EXPECT_EQ(result, utf_helper::UTF16_REPLACEMENT_CHARACTER);
uint16_t input1[] = {0xD800, 0x0041};
index = 0;
len = sizeof(input1) / sizeof(input1[0]);
result = utf_helper::HandleAndDecodeInvalidUTF16(input1, len, &index);
EXPECT_EQ(result, utf_helper::UTF16_REPLACEMENT_CHARACTER);
uint16_t input2[] = {0x0041};
index = 0;
len = sizeof(input2) / sizeof(input2[0]);
result = utf_helper::HandleAndDecodeInvalidUTF16(input2, len, &index);
EXPECT_EQ(result, 0x0041);
uint16_t input3[] = {0xDBFF};
index = 0;
len = sizeof(input3) / sizeof(input3[0]);
result = utf_helper::HandleAndDecodeInvalidUTF16(input3, len, &index);
EXPECT_EQ(result, utf_helper::UTF16_REPLACEMENT_CHARACTER);
uint16_t input4[] = {0xDFFF};
index = 0;
len = sizeof(input4) / sizeof(input4[0]);
result = utf_helper::HandleAndDecodeInvalidUTF16(input4, len, &index);
EXPECT_EQ(result, utf_helper::UTF16_REPLACEMENT_CHARACTER);
}
HWTEST_F_L0(UtfHelperTest, HandleAndDecodeInvalidUTF16Test2)
{
uint16_t input[] = {0xD800};
size_t index = 0;
size_t len = sizeof(input) / sizeof(input[0]);
uint32_t result = utf_helper::HandleAndDecodeInvalidUTF16(input, len, &index);
EXPECT_EQ(result, utf_helper::UTF16_REPLACEMENT_CHARACTER);
uint16_t input1[] = {0xD800, 0xD800};
size_t len1 = sizeof(input1) / sizeof(input1[0]);
result = utf_helper::HandleAndDecodeInvalidUTF16(input1, len1, &index);
EXPECT_EQ(result, utf_helper::UTF16_REPLACEMENT_CHARACTER);
uint16_t input2[] = {'A'};
size_t len2 = sizeof(input2) / sizeof(input2[0]);
result = utf_helper::HandleAndDecodeInvalidUTF16(input2, len2, &index);
EXPECT_EQ(result, 'A');
uint16_t input3[] = {0xD800 ^ 0x01};
size_t len3 = sizeof(input3) / sizeof(input3[0]);
result = utf_helper::HandleAndDecodeInvalidUTF16(input3, len3, &index);
EXPECT_EQ(result, utf_helper::UTF16_REPLACEMENT_CHARACTER);
}
HWTEST_F_L0(UtfHelperTest, HandleAndDecodeInvalidUTF16Test3)
{
uint16_t input[] = {0xDBFF, 0xDFFF};
size_t index = 0;
size_t len = sizeof(input) / sizeof(input[0]);
uint32_t expected = ((0xDBFF - utf_helper::DECODE_LEAD_LOW) << utf_helper::UTF16_OFFSET) +
(0xDFFF - utf_helper::DECODE_TRAIL_LOW) + utf_helper::DECODE_SECOND_FACTOR;
uint32_t result = utf_helper::HandleAndDecodeInvalidUTF16(input, len, &index);
EXPECT_EQ(result, expected);
}
HWTEST_F_L0(UtfHelperTest, HandleAndDecodeInvalidUTF16Test4)
{
uint16_t input[] = {0xD800, 0xDC00};
size_t index = 0;
size_t len = sizeof(input) / sizeof(input[0]);
uint32_t expected = ((0xD800 - utf_helper::DECODE_LEAD_LOW) << utf_helper::UTF16_OFFSET) +
(0xDC00 - utf_helper::DECODE_TRAIL_LOW) + utf_helper::DECODE_SECOND_FACTOR;
uint32_t result = utf_helper::HandleAndDecodeInvalidUTF16(input, len, &index);
EXPECT_EQ(result, expected);
EXPECT_EQ(index, 1);
}
HWTEST_F_L0(UtfHelperTest, IsValidUTF8Test1)
{
std::vector<uint8_t> data = {0xED, 0xA0, 0x80};
EXPECT_FALSE(utf_helper::IsValidUTF8(data));
std::vector<uint8_t> data1 = {0xED, 0x90, 0x80};
EXPECT_TRUE(utf_helper::IsValidUTF8(data1));
std::vector<uint8_t> data2 = {0xED, 0xC0, 0x80};
EXPECT_FALSE(utf_helper::IsValidUTF8(data2));
std::vector<uint8_t> data3 = {0xED, 0x80, 0x80};
EXPECT_TRUE(utf_helper::IsValidUTF8(data3));
std::vector<uint8_t> data4 = {0xE0, 0xA0, 0x80};
EXPECT_TRUE(utf_helper::IsValidUTF8(data4));
std::vector<uint8_t> data5 = {0xC2, 0xA9};
EXPECT_TRUE(utf_helper::IsValidUTF8(data5));
std::vector<uint8_t> data6 = {0xE2, 0x82, 0xAC};
EXPECT_TRUE(utf_helper::IsValidUTF8(data6));
}
HWTEST_F_L0(UtfHelperTest, IsValidUTF8Test2)
{
std::vector<uint8_t> data = {0xF4, 0x90, 0x80, 0x80};
EXPECT_FALSE(utf_helper::IsValidUTF8(data));
std::vector<uint8_t> data1 = {0xF5, 0x80, 0x80, 0x80};
EXPECT_FALSE(utf_helper::IsValidUTF8(data1));
std::vector<uint8_t> data2 = {0xF0, 0x90, 0x80, 0x80};
EXPECT_TRUE(utf_helper::IsValidUTF8(data2));
std::vector<uint8_t> data3 = {0xF1, 0x80, 0x80, 0x80};
EXPECT_TRUE(utf_helper::IsValidUTF8(data3));
std::vector<uint8_t> data4 = {0xF4, 0x80, 0x80, 0x80};
EXPECT_TRUE(utf_helper::IsValidUTF8(data4));
}
HWTEST_F_L0(UtfHelperTest, ConvertRegionUtf16ToUtf8Test3)
{
uint8_t utf8Out[10];
size_t result = utf_helper::ConvertRegionUtf16ToUtf8(nullptr, utf8Out, 5, 10, 0, false, false, false);
EXPECT_EQ(result, 0);
uint16_t utf16In[] = {0x0041};
result = utf_helper::ConvertRegionUtf16ToUtf8(utf16In, nullptr, 1, sizeof(utf16In), 0, false, false, false);
EXPECT_EQ(result, 0);
result = utf_helper::ConvertRegionUtf16ToUtf8(utf16In, utf8Out, 1, 0, 0, false, false, false);
EXPECT_EQ(result, 0);
result = utf_helper::ConvertRegionUtf16ToUtf8(nullptr, utf8Out, 1, 0, 0, false, false, false);
EXPECT_EQ(result, 0);
result = utf_helper::ConvertRegionUtf16ToUtf8(utf16In, nullptr, 1, 0, 0, false, false, false);
EXPECT_EQ(result, 0);
result = utf_helper::ConvertRegionUtf16ToUtf8(nullptr, nullptr, 1, sizeof(utf8Out), 0, false, false, false);
EXPECT_EQ(result, 0);
result = utf_helper::ConvertRegionUtf16ToUtf8(nullptr, nullptr, 1, 0, 0, false, false, false);
EXPECT_EQ(result, 0);
result = utf_helper::ConvertRegionUtf16ToUtf8(utf16In, utf8Out, 1, sizeof(utf8Out), 0, false, false, false);
EXPECT_EQ(result, 1);
}
HWTEST_F_L0(UtfHelperTest, ConvertRegionUtf16ToLatin1Test)
{
uint8_t utf8Out[10];
size_t result = utf_helper::ConvertRegionUtf16ToLatin1(nullptr, utf8Out, 5, 10);
EXPECT_EQ(result, 0);
uint16_t utf16In[] = {0x0041};
result = utf_helper::ConvertRegionUtf16ToLatin1(utf16In, nullptr, 1, sizeof(utf16In));
EXPECT_EQ(result, 0);
result = utf_helper::ConvertRegionUtf16ToLatin1(utf16In, utf8Out, 1, 0);
EXPECT_EQ(result, 0);
result = utf_helper::ConvertRegionUtf16ToLatin1(nullptr, utf8Out, 1, 0);
EXPECT_EQ(result, 0);
result = utf_helper::ConvertRegionUtf16ToLatin1(utf16In, nullptr, 1, 0);
EXPECT_EQ(result, 0);
result = utf_helper::ConvertRegionUtf16ToLatin1(nullptr, nullptr, 1, sizeof(utf8Out));
EXPECT_EQ(result, 0);
result = utf_helper::ConvertRegionUtf16ToLatin1(nullptr, nullptr, 1, 0);
EXPECT_EQ(result, 0);
result = utf_helper::ConvertRegionUtf16ToLatin1(utf16In, utf8Out, 1, sizeof(utf8Out));
EXPECT_EQ(result, 1);
const uint16_t input[] = {0x0041, 0x0042, 0x0043};
uint8_t output[2] = {0};
result = utf_helper::ConvertRegionUtf16ToLatin1(input, output, 3, 2);
EXPECT_EQ(result, 2);
}
HWTEST_F_L0(UtfHelperTest, DebuggerConvertRegionUtf16ToUtf8Test)
{
uint8_t utf8Out[10];
size_t result = utf_helper::DebuggerConvertRegionUtf16ToUtf8(nullptr, utf8Out, 5, sizeof(utf8Out), 0, false, false);
EXPECT_EQ(result, 0);
uint16_t utf16In[] = {0x0041};
result = utf_helper::DebuggerConvertRegionUtf16ToUtf8(utf16In, nullptr, 1, sizeof(utf16In), 0, false, false);
EXPECT_EQ(result, 0);
result = utf_helper::DebuggerConvertRegionUtf16ToUtf8(nullptr, nullptr, 1, sizeof(utf8Out), 0, false, false);
EXPECT_EQ(result, 0);
result = utf_helper::DebuggerConvertRegionUtf16ToUtf8(nullptr, utf8Out, 1, 0, 0, false, false);
EXPECT_EQ(result, 0);
result = utf_helper::DebuggerConvertRegionUtf16ToUtf8(nullptr, utf8Out, 1, 0, 0, false, false);
EXPECT_EQ(result, 0);
result = utf_helper::DebuggerConvertRegionUtf16ToUtf8(nullptr, nullptr, 1, 0, 0, false, false);
EXPECT_EQ(result, 0);
result = utf_helper::DebuggerConvertRegionUtf16ToUtf8(utf16In, utf8Out, 1, 0, 0, false, false);
EXPECT_EQ(result, 0);
result = utf_helper::DebuggerConvertRegionUtf16ToUtf8(utf16In, utf8Out, 1, sizeof(utf8Out), 0, false, false);
EXPECT_EQ(result, 1);
uint16_t utf16In1[] = {0x0041, 0x0042, 0x0043};
result = utf_helper::DebuggerConvertRegionUtf16ToUtf8(utf16In1, nullptr, 3, 0, 0, false, false);
EXPECT_EQ(result, 0);
}
HWTEST_F_L0(UtfHelperTest, DecodeUTF16Test4)
{
uint16_t utf16[] = {0xD800, 0xDC00};
size_t index = 0;
size_t len = sizeof(utf16) / sizeof(utf16[0]);
uint32_t result = utf_helper::DecodeUTF16(utf16, len, &index, false);
EXPECT_EQ(result, 0x10000);
EXPECT_EQ(index, 1);
}
HWTEST_F_L0(UtfHelperTest, Utf8ToUtf16Size_LastByteIsTwoByteStart_TrimLastByte)
{
const uint8_t utf8[] = {0xC0};
size_t utf8Len = sizeof(utf8);
size_t result = utf_helper::Utf8ToUtf16Size(utf8, utf8Len);
EXPECT_EQ(result, 1);
}
HWTEST_F_L0(UtfHelperTest, Utf8ToUtf16Size_LastTwoBytesStartWithThreeByteHeader_TrimTwoBytes)
{
const uint8_t utf8[] = {0xE2, 0x82};
size_t utf8Len = sizeof(utf8);
size_t result = utf_helper::Utf8ToUtf16Size(utf8, utf8Len);
EXPECT_EQ(result, 2);
}
HWTEST_F_L0(UtfHelperTest, Utf8ToUtf16Size_IncompleteSequenceAtEnd_ReturnsSizeWithoutInvalid)
{
const uint8_t utf8[] = {0xF0, 0x90, 0x8D};
size_t result = utf_helper::Utf8ToUtf16Size(utf8, 3);
EXPECT_EQ(result, 3);
}
HWTEST_F_L0(UtfHelperTest, DebuggerConvertRegionUtf16ToUtf8_ZeroCodepoint_WriteNulChar)
{
uint16_t utf16In[] = {0x0000};
uint8_t utf8Out[10] = {0};
size_t utf16Len = 1;
size_t utf8Len = sizeof(utf8Out);
size_t start = 0;
bool modify = false;
bool isWriteBuffer = true;
size_t result = utf_helper::DebuggerConvertRegionUtf16ToUtf8(
utf16In, utf8Out, utf16Len, utf8Len, start, modify, isWriteBuffer);
EXPECT_EQ(result, 1);
EXPECT_EQ(utf8Out[0], 0x00U);
}
HWTEST_F_L0(UtfHelperTest, ConvertUtf16ToUtf8_NulChar_WriteBufferMode_ReturnsZeroByte)
{
uint16_t d0 = 0x0000;
uint16_t d1 = 0;
bool modify = false;
bool isWriteBuffer = true;
utf_helper::Utf8Char result = utf_helper::ConvertUtf16ToUtf8(d0, d1, modify, isWriteBuffer);
EXPECT_EQ(result.n, 1);
EXPECT_EQ(result.ch[0], 0x00U);
}
}