From b44a606987a123c604127b1eb91b325137d79569 Mon Sep 17 00:00:00 2001 From: Basilisk-Dev Date: Fri, 15 May 2026 21:42:53 -0400 Subject: [PATCH] Fix ArrayBuffer storage and error types --- js/src/js.msg | 2 ++ .../non262/ArrayBuffer/resizable-transfer.js | 3 +++ js/src/vm/ArrayBufferObject.cpp | 24 +++++-------------- 3 files changed, 11 insertions(+), 18 deletions(-) diff --git a/js/src/js.msg b/js/src/js.msg index d8547ae4eb..c635bb54ed 100644 --- a/js/src/js.msg +++ b/js/src/js.msg @@ -548,6 +548,8 @@ MSG_DEF(JSMSG_TOO_LONG_ARRAY, 0, JSEXN_TYPEERR, "Too long array") // Typed array MSG_DEF(JSMSG_BAD_INDEX, 0, JSEXN_RANGEERR, "invalid or out-of-range index") +MSG_DEF(JSMSG_ARRAYBUFFER_NOT_RESIZABLE, 0, JSEXN_TYPEERR, "ArrayBuffer is not resizable") +MSG_DEF(JSMSG_ARRAYBUFFER_CANNOT_DETACH, 0, JSEXN_TYPEERR, "ArrayBuffer cannot be detached") MSG_DEF(JSMSG_NON_ARRAY_BUFFER_RETURNED, 0, JSEXN_TYPEERR, "expected ArrayBuffer, but species constructor returned non-ArrayBuffer") MSG_DEF(JSMSG_SAME_ARRAY_BUFFER_RETURNED, 0, JSEXN_TYPEERR, "expected different ArrayBuffer, but species constructor returned same ArrayBuffer") MSG_DEF(JSMSG_SHORT_ARRAY_BUFFER_RETURNED, 2, JSEXN_TYPEERR, "expected ArrayBuffer with at least {0} bytes, but species constructor returns ArrayBuffer with {1} bytes") diff --git a/js/src/tests/non262/ArrayBuffer/resizable-transfer.js b/js/src/tests/non262/ArrayBuffer/resizable-transfer.js index b05a0deffa..f603edabff 100644 --- a/js/src/tests/non262/ArrayBuffer/resizable-transfer.js +++ b/js/src/tests/non262/ArrayBuffer/resizable-transfer.js @@ -5,6 +5,9 @@ assertEq(fixed.byteLength, 4); assertEq(fixed.maxByteLength, 4); assertEq(fixed.resizable, false); assertEq(fixed.detached, false); +new Uint8Array(fixed).set([1, 2, 3, 4]); +fixed.extra = 17; +assertEq(Array.from(new Uint8Array(fixed)).join(","), "1,2,3,4"); assertThrowsInstanceOf(() => fixed.resize(2), TypeError); assertEq(ArrayBuffer.prototype.transfer.length, 0); assertEq(ArrayBuffer.prototype.transferToFixedLength.length, 0); diff --git a/js/src/vm/ArrayBufferObject.cpp b/js/src/vm/ArrayBufferObject.cpp index 2ac6ced5ff..666fc774df 100644 --- a/js/src/vm/ArrayBufferObject.cpp +++ b/js/src/vm/ArrayBufferObject.cpp @@ -409,14 +409,14 @@ AllocateArrayBufferContents(JSContext* cx, uint32_t nbytes) static bool ReportArrayBufferNotResizable(JSContext* cx) { - JS_ReportErrorASCII(cx, "ArrayBuffer is not resizable"); + JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_ARRAYBUFFER_NOT_RESIZABLE); return false; } static bool ReportArrayBufferCannotDetach(JSContext* cx) { - JS_ReportErrorASCII(cx, "ArrayBuffer cannot be detached"); + JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_ARRAYBUFFER_CANNOT_DETACH); return false; } @@ -1389,10 +1389,6 @@ ArrayBufferObject::create(JSContext* cx, uint32_t nbytes, BufferContents content return nullptr; } - // If we need to allocate data, try to use a larger object size class so - // that the array buffer's data can be allocated inline with the object. - // The extra space will be left unused by the object's fixed slots and - // available for the buffer's data, see NewObject(). size_t reservedSlots = JSCLASS_RESERVED_SLOTS(&class_); size_t nslots = reservedSlots; @@ -1409,18 +1405,10 @@ ArrayBufferObject::create(JSContext* cx, uint32_t nbytes, BufferContents content } } else { MOZ_ASSERT(ownsState == OwnsData); - size_t usableSlots = NativeObject::MAX_FIXED_SLOTS - reservedSlots; - if (nbytes <= usableSlots * sizeof(Value)) { - int newSlots = nbytes == 0 ? 0 : (nbytes - 1) / sizeof(Value) + 1; - MOZ_ASSERT(int(nbytes) <= newSlots * int(sizeof(Value))); - nslots = reservedSlots + newSlots; - contents = BufferContents::createPlain(nullptr); - } else { - contents = AllocateArrayBufferContents(cx, nbytes); - if (!contents) - return nullptr; - allocated = true; - } + contents = AllocateArrayBufferContents(cx, nbytes); + if (!contents) + return nullptr; + allocated = true; } MOZ_ASSERT(!(class_.flags & JSCLASS_HAS_PRIVATE));