Fix GetUtf8Length when get \0 length

Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IAF5RW?from=project-issue
Test: Build & Boot devices

Signed-off-by: wupengyong <wupengyong@huawei.com>
Change-Id: If5bac1d81320fccd4821569a369c4e3bfc2c2e7a
This commit is contained in:
wupengyong 2024-07-24 10:59:53 +08:00
parent be50acd63d
commit 956effcf4a
8 changed files with 24 additions and 14 deletions

View File

@ -311,6 +311,14 @@ HWTEST_F_L0(UtfHelperTest, Utf16ToUtf8Size_001)
length = Utf16ToUtf8Size(utf16ValuePtr3, 1, true);
EXPECT_EQ(length - 1, 2U);
// if isGetBufferSize is true, special case for U+0000 => 00
uint16_t utf16Value12[1] = {0x00};
const uint16_t *utf16ValuePtr12 = utf16Value12;
length = Utf16ToUtf8Size(utf16ValuePtr12, 1, false, true);
EXPECT_EQ(length - 1, 1U);
length = Utf16ToUtf8Size(utf16ValuePtr12, 1, true, true);
EXPECT_EQ(length - 1, 1U);
// code point lie in [0x00, 0x7F], it needs to be represented by one UTF8 code.
uint16_t utf16Value4[1] = {0x00};
uint16_t utf16Value5[1] = {0x7F};

View File

@ -215,7 +215,7 @@ Utf8Char ConvertUtf16ToUtf8(uint16_t d0, uint16_t d1, bool modify, bool isWriteB
return {UtfLength::FOUR, {ch0, ch1, ch2, ch3}};
}
size_t Utf16ToUtf8Size(const uint16_t *utf16, uint32_t length, bool modify)
size_t Utf16ToUtf8Size(const uint16_t *utf16, uint32_t length, bool modify, bool isGetBufferSize)
{
size_t res = 1; // zero byte
// when utf16 data length is only 1 and code in 0xd800-0xdfff,
@ -228,7 +228,9 @@ size_t Utf16ToUtf8Size(const uint16_t *utf16, uint32_t length, bool modify)
for (uint32_t i = 0; i < length; ++i) {
if (utf16[i] == 0) { // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
if (modify) {
if (isGetBufferSize) {
res += UtfLength::ONE;
} else if (modify) {
res += UtfLength::TWO; // special case for U+0000 => C0 80
}
} else if (utf16[i] <= UTF8_1B_MAX) { // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)

View File

@ -87,7 +87,7 @@ bool IsValidUTF8(const std::vector<uint8_t> &data);
Utf8Char ConvertUtf16ToUtf8(uint16_t d0, uint16_t d1, bool modify, bool isWriteBuffer = false);
size_t Utf16ToUtf8Size(const uint16_t *utf16, uint32_t length, bool modify = true);
size_t Utf16ToUtf8Size(const uint16_t *utf16, uint32_t length, bool modify = true, bool isGetBufferSize = false);
size_t PUBLIC_API ConvertRegionUtf16ToUtf8(const uint16_t *utf16In, uint8_t *utf8Out, size_t utf16Len, size_t utf8Len,
size_t start, bool modify = true, bool isWriteBuffer = false);

View File

@ -291,14 +291,14 @@ inline uint16_t *EcmaString::GetDataUtf16Writable()
return GetData();
}
inline size_t EcmaString::GetUtf8Length(bool modify) const
inline size_t EcmaString::GetUtf8Length(bool modify, bool isGetBufferSize) const
{
if (!IsUtf16()) {
return GetLength() + 1; // add place for zero in the end
}
CVector<uint16_t> tmpBuf;
const uint16_t *data = GetUtf16DataFlat(this, tmpBuf);
return base::utf_helper::Utf16ToUtf8Size(data, GetLength(), modify);
return base::utf_helper::Utf16ToUtf8Size(data, GetLength(), modify, isGetBufferSize);
}
template<bool verify>
@ -502,9 +502,9 @@ inline const uint16_t *EcmaStringAccessor::GetDataUtf16()
return string_->GetDataUtf16();
}
inline size_t EcmaStringAccessor::GetUtf8Length() const
inline size_t EcmaStringAccessor::GetUtf8Length(bool isGetBufferSize) const
{
return string_->GetUtf8Length();
return string_->GetUtf8Length(true, isGetBufferSize);
}
inline void EcmaStringAccessor::ReadData(EcmaString *dst, EcmaString *src,

View File

@ -198,7 +198,7 @@ private:
SetMixHashcode(MixHashcode(hashcode, isInteger));
}
inline size_t GetUtf8Length(bool modify = true) const;
inline size_t GetUtf8Length(bool modify = true, bool isGetBufferSize = false) const;
inline void SetIsInternString()
{
@ -1156,7 +1156,7 @@ public:
}
// require is LineString
inline size_t GetUtf8Length() const;
inline size_t GetUtf8Length(bool isGetBufferSize = false) const;
size_t ObjectSize() const
{

View File

@ -862,7 +862,7 @@ public:
std::string ToString(const EcmaVM *vm);
std::string DebuggerToString(const EcmaVM *vm);
uint32_t Length(const EcmaVM *vm);
int32_t Utf8Length(const EcmaVM *vm);
int32_t Utf8Length(const EcmaVM *vm, bool isGetBufferSize = false);
int WriteUtf8(const EcmaVM *vm, char *buffer, int length, bool isWriteBuffer = false);
int WriteUtf16(const EcmaVM *vm, char16_t *buffer, int length);
int WriteLatin1(const EcmaVM *vm, char *buffer, int length);

View File

@ -1997,12 +1997,12 @@ uint32_t StringRef::Length([[maybe_unused]] const EcmaVM *vm)
return EcmaStringAccessor(JSNApiHelper::ToJSTaggedValue(this)).GetLength();
}
int32_t StringRef::Utf8Length(const EcmaVM *vm)
int32_t StringRef::Utf8Length(const EcmaVM *vm, bool isGetBufferSize)
{
DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
JSHandle<EcmaString> strHandle(vm->GetJSThread(), EcmaString::Cast(JSNApiHelper::ToJSTaggedValue(this)));
return EcmaStringAccessor(EcmaStringAccessor::Flatten(vm, strHandle)).GetUtf8Length();
return EcmaStringAccessor(EcmaStringAccessor::Flatten(vm, strHandle)).GetUtf8Length(isGetBufferSize);
}
int StringRef::WriteUtf8([[maybe_unused]] const EcmaVM *vm, char *buffer, int length, bool isWriteBuffer)

View File

@ -358,7 +358,7 @@ HWTEST_F_L0(JSNApiTests, StringUtf8_003)
// isWriteBuffer == false, \u0000 ==> C080
Local<StringRef> testString1 = StringRef::NewFromUtf8(vm_, test.c_str(), test.length());
EXPECT_EQ(testString1->Utf8Length(vm_), 5);
EXPECT_EQ(testString1->Utf8Length(vm_, false), 5);
char buffer1[4];
testString1->WriteUtf8(vm_, buffer1, 4, false);
EXPECT_EQ(buffer1[0], 'a');
@ -368,7 +368,7 @@ HWTEST_F_L0(JSNApiTests, StringUtf8_003)
// isWriteBuffer == true, \u0000 ==> 0x00U
Local<StringRef> testString2 = StringRef::NewFromUtf8(vm_, test.c_str(), test.length());
EXPECT_EQ(testString2->Utf8Length(vm_), 5);
EXPECT_EQ(testString2->Utf8Length(vm_, true), 4);
char buffer2[4];
testString2->WriteUtf8(vm_, buffer2, 4, true);
EXPECT_EQ(buffer2[0], 'a');