Bugfix on EcmaString::CreateTreeString create long ecmaString

Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I7R95U

Signed-off-by: quiet-thought <chenjingxiang1@huawei.com>
Change-Id: Iaebdd8f8fa998b10124894e61a304b6957b11f57
This commit is contained in:
quiet-thought 2023-08-07 20:49:05 +08:00
parent a9538dd60f
commit 8e3717baf4
8 changed files with 40 additions and 9 deletions

View File

@ -927,8 +927,12 @@ JSTaggedValue BuiltinsString::Replace(EcmaRuntimeCallInfo *argv)
auto thisLen = EcmaStringAccessor(thisString).GetLength();
JSHandle<EcmaString> suffixString(thread,
EcmaStringAccessor::FastSubString(ecmaVm, thisString, tailPos, thisLen - tailPos));
JSHandle<EcmaString> tempString(thread, EcmaStringAccessor::Concat(ecmaVm, prefixString, realReplaceStr));
return JSTaggedValue(EcmaStringAccessor::Concat(ecmaVm, tempString, suffixString));
EcmaString *tempStr = EcmaStringAccessor::Concat(ecmaVm, prefixString, realReplaceStr);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
JSHandle<EcmaString> tempString(thread, tempStr);
EcmaString *resultStr = EcmaStringAccessor::Concat(ecmaVm, tempString, suffixString);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
return JSTaggedValue(resultStr);
}
JSTaggedValue BuiltinsString::ReplaceAll(EcmaRuntimeCallInfo *argv)

View File

@ -154,6 +154,7 @@ inline EcmaString *EcmaString::CreateConstantString(const EcmaVM *vm, const uint
inline EcmaString *EcmaString::CreateTreeString(const EcmaVM *vm,
const JSHandle<EcmaString> &left, const JSHandle<EcmaString> &right, uint32_t length, bool compressed)
{
ECMA_STRING_CHECK_LENGTH_AND_TRHOW(vm, length);
auto thread = vm->GetJSThread();
auto string = TreeEcmaString::Cast(vm->GetFactory()->AllocTreeStringObject());
string->SetLength(length, compressed);

View File

@ -43,12 +43,19 @@ class LineEcmaString;
class ConstantString;
class TreeEcmaString;
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define ECMA_STRING_CHECK_LENGTH_AND_TRHOW(vm, length) \
if ((length) >= MAX_STRING_LENGTH) { \
THROW_RANGE_ERROR_AND_RETURN((vm)->GetJSThread(), "Invalid string length", nullptr); \
}
class EcmaString : public TaggedObject {
public:
CAST_CHECK(EcmaString, IsString);
static constexpr uint32_t STRING_COMPRESSED_BIT = 0x1;
static constexpr uint32_t STRING_INTERN_BIT = 0x2;
static constexpr size_t MAX_STRING_LENGTH = 0x40000000U; // 30 bits for string length, 2 bits for special meaning
static constexpr size_t MIX_LENGTH_OFFSET = TaggedObjectSize();
// In last bit of mix_length we store if this string is compressed or not.
@ -130,7 +137,7 @@ private:
void SetLength(uint32_t length, bool compressed = false)
{
ASSERT(length < 0x40000000U);
ASSERT(length < MAX_STRING_LENGTH);
// Use 0u for compressed/utf8 expression
SetMixLength((length << 2U) | (compressed ? STRING_COMPRESSED : STRING_UNCOMPRESSED));
}

View File

@ -68,6 +68,7 @@ public:
JSHandle<EcmaString> stringA0 = JSHandle<EcmaString>(JSHandle<JSTaggedValue>(thread, left));
JSHandle<EcmaString> stringA1 = JSHandle<EcmaString>(JSHandle<JSTaggedValue>(thread, right));
EcmaString *ret = EcmaStringAccessor::Concat(thread->GetEcmaVM(), stringA0, stringA1);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
return JSTaggedValue(ret);
}
// Support cases, such as: string + null, string + object, string + boolean, string + number, etc.
@ -79,12 +80,14 @@ public:
JSHandle<EcmaString> stringA1 = JSTaggedValue::ToString(thread, rightValue);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
EcmaString *ret = EcmaStringAccessor::Concat(thread->GetEcmaVM(), stringA0, stringA1);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
return JSTaggedValue(ret);
} else {
JSHandle<EcmaString> stringA0 = JSTaggedValue::ToString(thread, leftValue);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
JSHandle<EcmaString> stringA1 = JSHandle<EcmaString>(rightValue);
EcmaString *ret = EcmaStringAccessor::Concat(thread->GetEcmaVM(), stringA0, stringA1);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
return JSTaggedValue(ret);
}
}

View File

@ -1466,8 +1466,10 @@ JSTaggedValue RuntimeStubs::RuntimeAdd2(JSThread *thread, const JSHandle<JSTagge
const JSHandle<JSTaggedValue> &right)
{
if (left->IsString() && right->IsString()) {
return JSTaggedValue(EcmaStringAccessor::Concat(
thread->GetEcmaVM(), JSHandle<EcmaString>(left), JSHandle<EcmaString>(right)));
EcmaString *resultStr = EcmaStringAccessor::Concat(
thread->GetEcmaVM(), JSHandle<EcmaString>(left), JSHandle<EcmaString>(right));
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
return JSTaggedValue(resultStr);
}
JSHandle<JSTaggedValue> primitiveA0(thread, JSTaggedValue::ToPrimitive(thread, left));
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
@ -1479,7 +1481,9 @@ JSTaggedValue RuntimeStubs::RuntimeAdd2(JSThread *thread, const JSHandle<JSTagge
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
JSHandle<EcmaString> stringA1 = JSTaggedValue::ToString(thread, primitiveA1);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
return JSTaggedValue(EcmaStringAccessor::Concat(thread->GetEcmaVM(), stringA0, stringA1));
EcmaString *resultStr = EcmaStringAccessor::Concat(thread->GetEcmaVM(), stringA0, stringA1);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
return JSTaggedValue(resultStr);
}
JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, primitiveA0);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);

View File

@ -56,7 +56,7 @@ public:
HWTEST_F_L0(LineEcmaStringTest, ComputeSizeUtf8)
{
uint32_t scale = 3333;
for (uint32_t i = 0x40000000U - 1; i > scale; i = i - scale) {
for (uint32_t i = EcmaString::MAX_STRING_LENGTH - 1; i > scale; i = i - scale) {
uint32_t length = i;
EXPECT_EQ(LineEcmaString::ComputeSizeUtf8(length), length + LineEcmaString::SIZE);
}
@ -71,7 +71,7 @@ HWTEST_F_L0(LineEcmaStringTest, ComputeSizeUtf8)
HWTEST_F_L0(LineEcmaStringTest, ComputeSizeUtf16)
{
uint32_t scale = 3333;
for (uint32_t i = 0x40000000U - 1; i > scale; i = i - scale) {
for (uint32_t i = EcmaString::MAX_STRING_LENGTH - 1; i > scale; i = i - scale) {
uint32_t length = i;
EXPECT_EQ(LineEcmaString::ComputeSizeUtf16(length), 2 * length + LineEcmaString::SIZE);
}

View File

@ -16,3 +16,4 @@ false
true
true
false
Invalid string length

View File

@ -34,4 +34,15 @@ let utf81 = '1231246334765963428744656876534423435679865345567889986574643532345
let utf82 = utf81.substring(0, 169) + '8';
let utf83 = utf81.substring(0, 169) + '0';
print((utf81 === utf82).toString());
print((utf81 === utf83).toString());
print((utf81 === utf83).toString());
function foo(a) {
return a;
}
try {
for (let i = 0; i < 25; i++) {
foo += foo;
}
} catch (e) {
print(e.message);
}