diff --git a/ecmascript/base/typed_array_helper.cpp b/ecmascript/base/typed_array_helper.cpp index c86002dbdf9067825ecd8935c2f46954b47d3276..89ffed8b3ff112a271c8a074967b7b5e8ebe2f6f 100644 --- a/ecmascript/base/typed_array_helper.cpp +++ b/ecmascript/base/typed_array_helper.cpp @@ -324,11 +324,11 @@ JSTaggedValue TypedArrayHelper::CreateFromArrayBuffer(EcmaRuntimeCallInfo *argv, // 8. If length is not undefined, then // a. Let newLength be ? ToIndex(length). JSHandle length = BuiltinsBase::GetCallArg(argv, BuiltinsBase::ArgsPosition::THIRD); - int32_t newLength = 0; + uint64_t newLength = 0; if (!length->IsUndefined()) { index = JSTaggedValue::ToIndex(thread, length); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - newLength = static_cast(index.GetNumber()); + newLength = static_cast(index.GetNumber()); } // 9. If IsDetachedBuffer(buffer) is true, throw a TypeError exception. JSHandle buffer = BuiltinsBase::GetCallArg(argv, 0); @@ -341,7 +341,7 @@ JSTaggedValue TypedArrayHelper::CreateFromArrayBuffer(EcmaRuntimeCallInfo *argv, // a. If bufferByteLength modulo elementSize ≠ 0, throw a RangeError exception. // b. Let newByteLength be bufferByteLength - offset. // c. If newByteLength < 0, throw a RangeError exception. - uint32_t newByteLength = 0; + uint64_t newByteLength = 0; if (length->IsUndefined()) { if (bufferByteLength % elementSize != 0) { THROW_RANGE_ERROR_AND_RETURN(thread, "The bufferByteLength cannot be an integral multiple of elementSize.", @@ -355,9 +355,7 @@ JSTaggedValue TypedArrayHelper::CreateFromArrayBuffer(EcmaRuntimeCallInfo *argv, // 12. Else, // a. Let newByteLength be newLength × elementSize. // b. If offset + newByteLength > bufferByteLength, throw a RangeError exception. - ASSERT((static_cast(newLength) * static_cast(elementSize)) <= - static_cast(INT32_MAX)); - newByteLength = static_cast(newLength) * elementSize; + newByteLength = newLength * elementSize; if (offset + newByteLength > bufferByteLength) { THROW_RANGE_ERROR_AND_RETURN(thread, "The newByteLength is out of range.", JSTaggedValue::Exception()); } diff --git a/ecmascript/builtins/builtins_typedarray.cpp b/ecmascript/builtins/builtins_typedarray.cpp index 5426e326ae337a0957d1fb203a65dfbc54a25584..58ac7951adf21e9e73625b3706693cbc77820420 100644 --- a/ecmascript/builtins/builtins_typedarray.cpp +++ b/ecmascript/builtins/builtins_typedarray.cpp @@ -1018,13 +1018,13 @@ JSTaggedValue BuiltinsTypedArray::Set(EcmaRuntimeCallInfo *argv) // 5. Assert: target has a [[ViewedArrayBuffer]] internal slot. // 6. Let targetOffset be ToInteger (offset). const JSHandle srcOffset = GetCallArg(argv, 1); - uint32_t targetOffset = 0; + uint64_t targetOffset = 0; if (srcOffset->IsInt()) { if (srcOffset->GetInt() < 0) { THROW_RANGE_ERROR_AND_RETURN(thread, "The targetOffset of This value is less than 0.", JSTaggedValue::Exception()); } - targetOffset = static_cast(srcOffset->GetInt()); + targetOffset = static_cast(srcOffset->GetInt()); } else { JSTaggedNumber tTargetOffset = JSTaggedValue::ToInteger(thread, srcOffset); // 7. ReturnIfAbrupt(targetOffset). @@ -1038,7 +1038,7 @@ JSTaggedValue BuiltinsTypedArray::Set(EcmaRuntimeCallInfo *argv) THROW_RANGE_ERROR_AND_RETURN(thread, "The targetOffset is infinty, which is greater than targetLength.", JSTaggedValue::Exception()); } else { - targetOffset = static_cast(rawTargetOffset); + targetOffset = static_cast(rawTargetOffset); } } // 9. Let targetBuffer be the value of target’s [[ViewedArrayBuffer]] internal slot. @@ -1093,7 +1093,7 @@ JSTaggedValue BuiltinsTypedArray::Set(EcmaRuntimeCallInfo *argv) JSTaggedValue::Exception()); } // 21. Let targetByteIndex be targetOffset × targetElementSize + targetByteOffset. - ASSERT((static_cast(targetOffset) * static_cast(targetElementSize) + + ASSERT((targetOffset * static_cast(targetElementSize) + static_cast(targetByteOffset)) <= static_cast(UINT32_MAX)); uint32_t targetByteIndex = static_cast(targetOffset * targetElementSize + targetByteOffset); // 22. Let k be 0. @@ -1192,9 +1192,9 @@ JSTaggedValue BuiltinsTypedArray::Set(EcmaRuntimeCallInfo *argv) srcByteIndex = srcByteOffset; } // 26. Let targetByteIndex be targetOffset × targetElementSize + targetByteOffset. - ASSERT((static_cast(targetOffset) * static_cast(targetElementSize) + + ASSERT((targetOffset * static_cast(targetElementSize) + static_cast(targetByteOffset)) <= static_cast(UINT32_MAX)); - uint32_t targetByteIndex = targetOffset * targetElementSize + targetByteOffset; + uint32_t targetByteIndex = static_cast(targetOffset) * targetElementSize + targetByteOffset; // 27. Let limit be targetByteIndex + targetElementSize × srcLength. ASSERT((static_cast(targetElementSize) * static_cast(srcLength) + static_cast(targetByteIndex)) <= static_cast(UINT32_MAX)); diff --git a/ecmascript/js_stable_array.cpp b/ecmascript/js_stable_array.cpp index 209e2afe3b5170691e5ce992ba24b18ab992c9b1..bffa1dbe8056bb819f801aae9d237b6d8ef5086b 100644 --- a/ecmascript/js_stable_array.cpp +++ b/ecmascript/js_stable_array.cpp @@ -661,7 +661,7 @@ JSTaggedValue JSStableArray::Concat(JSThread *thread, JSHandle newArra } JSTaggedValue JSStableArray::FastCopyFromArrayToTypedArray(JSThread *thread, JSHandle &targetArray, - DataViewType targetType, uint32_t targetOffset, + DataViewType targetType, uint64_t targetOffset, uint32_t srcLength, JSHandle &elements) { JSHandle targetBuffer(thread, targetArray->GetViewedArrayBufferOrByteArray()); @@ -673,7 +673,7 @@ JSTaggedValue JSStableArray::FastCopyFromArrayToTypedArray(JSThread *thread, JSH uint32_t targetLength = targetArray->GetArrayLength(); uint32_t targetByteOffset = targetArray->GetByteOffset(); uint32_t targetElementSize = TypedArrayHelper::GetSizeFromType(targetType); - if (srcLength + static_cast(targetOffset) > targetLength) { + if (srcLength + targetOffset > targetLength) { THROW_RANGE_ERROR_AND_RETURN(thread, "The sum of length and targetOffset is greater than targetLength.", JSTaggedValue::Exception()); } diff --git a/ecmascript/js_stable_array.h b/ecmascript/js_stable_array.h index 77fede8debaf8314a6f9a670efa84d0cce13238f..799be9e1cc7fa9fd9ad1c8442997a0e0b895a97b 100644 --- a/ecmascript/js_stable_array.h +++ b/ecmascript/js_stable_array.h @@ -54,7 +54,7 @@ public: static JSTaggedValue Concat(JSThread *thread, JSHandle newArrayHandle, JSHandle thisObjHandle, int64_t &k, int64_t &n); static JSTaggedValue FastCopyFromArrayToTypedArray(JSThread *thread, JSHandle &target, - DataViewType targetType, uint32_t targetOffset, + DataViewType targetType, uint64_t targetOffset, uint32_t srcLength, JSHandle &elements); static JSTaggedValue At(JSHandle receiver, EcmaRuntimeCallInfo *argv); static JSTaggedValue With(JSThread *thread, JSHandle receiver, diff --git a/test/moduletest/typearray/expect_output.txt b/test/moduletest/typearray/expect_output.txt index 38cb059fdbe2cb9f9f89da2f2670cab3df127402..51d53c62c313b61d97198e4e486b9cc67c3cd2ef 100644 --- a/test/moduletest/typearray/expect_output.txt +++ b/test/moduletest/typearray/expect_output.txt @@ -34,3 +34,6 @@ test successful !!! RangeError 0,0,0,0 not-equal +RangeError: The sum of srcLength and targetOffset is greater than targetLength. +RangeError: The sum of srcLength and targetOffset is greater than targetLength. +RangeError: The newByteLength is out of range. diff --git a/test/moduletest/typearray/typearray.js b/test/moduletest/typearray/typearray.js index 58c1735b28e7061a4cdb108c5cc1bb413b682b91..2ff1b835ab47e4ca3aa24dcb9aa08634ae10b505 100644 --- a/test/moduletest/typearray/typearray.js +++ b/test/moduletest/typearray/typearray.js @@ -231,3 +231,25 @@ const v22 = new BigInt64Array(v21); Atomics.or(v22, Int16Array, false); print(v22); print(Atomics.wait(v22, false, true)); + +try { + const v17 = new Int16Array(5); + const v20 = new Int16Array(5); + v17.set(v20, 4294967295); +} catch (error) { + print(error) +} + +try { + const v17 = new Int16Array(5); + const v20 = new Int16Array(5); + v17.set(v20, 4294967296); +} catch (error) { + print(error) +} + +try { + new BigUint64Array(new ArrayBuffer(256), 256, 0x1fffffff) +} catch (error) { + print(error) +}