diff --git a/lib/buffer.js b/lib/buffer.js index 22bbb95eaf79e6..4b755e1e3f0d22 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -593,6 +593,15 @@ Buffer.concat = function concat(list, length) { validateOffset(length, 'length'); } + // If there is only one FastBuffer, rotate without copying + if ( + list.length === 1 && + list[0] instanceof FastBuffer && + list[0].length === length + ) { + return Buffer.from(list[0]); + } + const buffer = Buffer.allocUnsafe(length); let pos = 0; for (let i = 0; i < list.length; i++) { diff --git a/test/parallel/test-buffer-concat.js b/test/parallel/test-buffer-concat.js index 2e7541fb58b063..3531f98de8059d 100644 --- a/test/parallel/test-buffer-concat.js +++ b/test/parallel/test-buffer-concat.js @@ -44,6 +44,18 @@ assert.notStrictEqual(flatOne, one[0]); assert.strictEqual(flatLong.toString(), check); assert.strictEqual(flatLongLen.toString(), check); +{ + const original = Buffer.from('fast'); + const result = Buffer.concat([original], original.length); + + const msgRef = + 'Buffer.concat should return a new Buffer instance even with single FastBuffer'; + const msgEq = 'Buffer.concat output should equal original content'; + + assert.notStrictEqual(result, original, msgRef); + assert.deepStrictEqual(result, original, msgEq); +} + [undefined, null, Buffer.from('hello')].forEach((value) => { assert.throws(() => { Buffer.concat(value);