From 0e5745978de8cc7314410e74cb44b20a09740872 Mon Sep 17 00:00:00 2001 From: Yijia Huang Date: Thu, 2 Nov 2023 12:46:08 -0700 Subject: [PATCH] JSC should throw an exception when BigUint64Array copy value from Int32Array https://bugs.webkit.org/show_bug.cgi?id=263954 rdar://117816146 Reviewed by Yusuke Suzuki. BigInt array set for non-BigInt typed array should throw exceptions. So, we shouldn't copy non-BigInt values from other typed array to BigInt for TypedArray.prototype.set. * JSTests/stress/bigint-array-set.js: Added. (i.catch): * Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h: (JSC::JSGenericTypedArrayView::copyFromInt32ShapeArray): (JSC::JSGenericTypedArrayView::copyFromDoubleShapeArray): (JSC::JSGenericTypedArrayView::setFromArrayLike): Canonical link: https://commits.webkit.org/270133@main --- JSTests/stress/bigint-array-set.js | 14 ++++++++++++++ .../runtime/JSGenericTypedArrayViewInlines.h | 6 +++--- 2 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 JSTests/stress/bigint-array-set.js diff --git a/JSTests/stress/bigint-array-set.js b/JSTests/stress/bigint-array-set.js new file mode 100644 index 000000000000..537e34821e29 --- /dev/null +++ b/JSTests/stress/bigint-array-set.js @@ -0,0 +1,14 @@ +//@ runDefault("--jitPolicyScale=0") +for (let i = 1; i < 1e3; i++) { + const v2 = [1000]; + const v4 = new BigUint64Array(i); + let thrown = false; + try { + v4.set(v2); + } catch (e6) { + thrown = true; + } + if (!thrown) + throw new Error("bad"); + Object.defineProperty(v2, 10, { writable: true, value: 10 }); +} diff --git a/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h b/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h index 0a1891801ebb..5f93c533982d 100644 --- a/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h +++ b/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h @@ -347,7 +347,7 @@ void JSGenericTypedArrayView::copyFromInt32ShapeArray(size_t offset, JS { ASSERT(canAccessRangeQuickly(offset, length)); ASSERT((array->indexingType() & IndexingShapeMask) == Int32Shape); - ASSERT(Adaptor::typeValue != TypeBigInt64 || Adaptor::typeValue != TypeBigUint64); + ASSERT(Adaptor::typeValue != TypeBigInt64 && Adaptor::typeValue != TypeBigUint64); ASSERT((length + objectOffset) <= array->length()); ASSERT(array->isIteratorProtocolFastAndNonObservable()); @@ -380,7 +380,7 @@ void JSGenericTypedArrayView::copyFromDoubleShapeArray(size_t offset, J { ASSERT(canAccessRangeQuickly(offset, length)); ASSERT((array->indexingType() & IndexingShapeMask) == DoubleShape); - ASSERT(Adaptor::typeValue != TypeBigInt64 || Adaptor::typeValue != TypeBigUint64); + ASSERT(Adaptor::typeValue != TypeBigInt64 && Adaptor::typeValue != TypeBigUint64); ASSERT((length + objectOffset) <= array->length()); ASSERT(array->isIteratorProtocolFastAndNonObservable()); @@ -411,7 +411,7 @@ bool JSGenericTypedArrayView::setFromArrayLike(JSGlobalObject* globalOb size_t safeUnadjustedLength = std::min(length, static_cast(MAX_ARRAY_INDEX) + 1); size_t safeLength = objectOffset <= safeUnadjustedLength ? safeUnadjustedLength - objectOffset : 0; - if constexpr (TypedArrayStorageType != TypeBigInt64 || TypedArrayStorageType != TypeBigUint64) { + if constexpr (TypedArrayStorageType != TypeBigInt64 && TypedArrayStorageType != TypeBigUint64) { if (JSArray* array = jsDynamicCast(object); LIKELY(array && isJSArray(array))) { if (safeLength == length && (safeLength + objectOffset) <= array->length() && array->isIteratorProtocolFastAndNonObservable()) { IndexingType indexingType = array->indexingType() & IndexingShapeMask;