mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 18:38:55 +00:00
fix(buffer): return fixed-length view from slice on resizable ArrayBuffer
Buffer.slice() on a resizable/growable ArrayBuffer was passing std::nullopt to JSUint8Array::create(), creating a length-tracking view that expanded when the buffer grew. Pass newLength instead to match Node.js behavior where slice always returns a fixed-length view. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1957,7 +1957,7 @@ static JSC::EncodedJSValue jsBufferPrototypeFunction_sliceBody(JSC::JSGlobalObje
|
||||
|
||||
if (castedThis->isResizableOrGrowableShared()) {
|
||||
auto* subclassStructure = globalObject->JSResizableOrGrowableSharedBufferSubclassStructure();
|
||||
auto* uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, WTF::move(buffer), byteOffset + startOffset, std::nullopt);
|
||||
auto* uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, WTF::move(buffer), byteOffset + startOffset, newLength);
|
||||
RETURN_IF_EXCEPTION(throwScope, {});
|
||||
if (!uint8Array) [[unlikely]] {
|
||||
throwOutOfMemoryError(globalObject, throwScope);
|
||||
|
||||
@@ -930,6 +930,25 @@ for (let withOverridenBufferWrite of [false, true]) {
|
||||
expect(() => buf.subarray(0, 5)).toThrow(TypeError);
|
||||
});
|
||||
|
||||
it("slice() on resizable ArrayBuffer returns fixed-length view", () => {
|
||||
const rab = new ArrayBuffer(10, { maxByteLength: 20 });
|
||||
const buf = Buffer.from(rab);
|
||||
buf[0] = 1;
|
||||
buf[1] = 2;
|
||||
buf[2] = 3;
|
||||
buf[3] = 4;
|
||||
buf[4] = 5;
|
||||
|
||||
const sliced = buf.slice(0, 5);
|
||||
expect(sliced.length).toBe(5);
|
||||
expect(sliced[0]).toBe(1);
|
||||
expect(sliced[4]).toBe(5);
|
||||
|
||||
// Growing the buffer should NOT change the slice length
|
||||
rab.resize(20);
|
||||
expect(sliced.length).toBe(5);
|
||||
});
|
||||
|
||||
function forEachUnicode(label, test) {
|
||||
["ucs2", "ucs-2", "utf16le", "utf-16le"].forEach(encoding =>
|
||||
it(`${label} (${encoding})`, test.bind(null, encoding)),
|
||||
|
||||
Reference in New Issue
Block a user