From 0173571b19780ab71772b1efcb9c4e623cab0aca Mon Sep 17 00:00:00 2001 From: Ai Hoshino Date: Thu, 19 Oct 2023 05:30:53 +0800 Subject: [PATCH] fix(node:buffer): fix the behavior of `totalLength` in `Buffer.concat` (#6574) * fix(node:buffer): fix the behavior of `totalLength` in `Buffer.concat` Close: #6570 Close: #3639 * fix buffer totalLength type --------- Co-authored-by: Ashcon Partovi --- src/bun.js/bindings/JSBuffer.cpp | 12 +++++++++--- test/js/node/buffer.test.js | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/bun.js/bindings/JSBuffer.cpp b/src/bun.js/bindings/JSBuffer.cpp index 524007f86a..543ef2ea38 100644 --- a/src/bun.js/bindings/JSBuffer.cpp +++ b/src/bun.js/bindings/JSBuffer.cpp @@ -742,10 +742,16 @@ static inline JSC::EncodedJSValue jsBufferConstructorFunction_concatBody(JSC::JS byteLength += typedArray->length(); } - if (callFrame->argumentCount() > 1) { - auto byteLengthValue = callFrame->uncheckedArgument(1); - byteLength = std::min(byteLength, byteLengthValue.toTypedArrayIndex(lexicalGlobalObject, "totalLength must be a valid number"_s)); + JSValue totalLengthValue = callFrame->argument(1); + if (!totalLengthValue.isUndefined()) { + if (UNLIKELY(!totalLengthValue.isNumber())) { + throwTypeError(lexicalGlobalObject, throwScope, "totalLength must be a valid number"_s); + return JSValue::encode(jsUndefined()); + } + + auto totalLength = totalLengthValue.toTypedArrayIndex(lexicalGlobalObject, "totalLength must be a valid number"_s); RETURN_IF_EXCEPTION(throwScope, {}); + byteLength = totalLength; } if (byteLength == 0) { diff --git a/test/js/node/buffer.test.js b/test/js/node/buffer.test.js index 0256934ce1..450129b0ec 100644 --- a/test/js/node/buffer.test.js +++ b/test/js/node/buffer.test.js @@ -1327,6 +1327,20 @@ it("Buffer.concat", () => { expect(Buffer.concat([array1, array2, array3], 222).length).toBe(222); expect(Buffer.concat([array1, array2, array3], 222).subarray(0, 128).join("")).toBe("100".repeat(128)); expect(Buffer.concat([array1, array2, array3], 222).subarray(129, 222).join("")).toBe("200".repeat(222 - 129)); + expect(() => { + Buffer.concat([array1], -1); + }).toThrow(RangeError); + expect(() => { + Buffer.concat([array1], "1"); + }).toThrow(TypeError); + // issue#6570 + expect(Buffer.concat([array1, array2, array3], undefined).join("")).toBe( + array1.join("") + array2.join("") + array3.join(""), + ); + // issue#3639 + expect(Buffer.concat([array1, array2, array3], 128 * 4).join("")).toBe( + array1.join("") + array2.join("") + array3.join("") + Buffer.alloc(128).join(""), + ); }); it("read", () => {