From 9c1098ebd1a772423682063c05c07f1a5297054a Mon Sep 17 00:00:00 2001 From: Lindsay Date: Tue, 13 Jan 2026 09:56:30 +0200 Subject: [PATCH] buffer: recreate pool after transfer Fixes: https://github.com/nodejs/node/issues/61362 --- lib/buffer.js | 9 +++++++++ test/parallel/test-buffer-pool-untransferable.js | 13 +++++++++++++ 2 files changed, 22 insertions(+) diff --git a/lib/buffer.js b/lib/buffer.js index dc189712fda29f..d2e033be4897d5 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -160,6 +160,12 @@ function createPool() { } createPool(); +function ensurePool() { + // Recreate the pool if it was detached (e.g., via ArrayBuffer.prototype.transfer). + if (allocPool.byteLength === 0) + createPool(); +} + function alignPool() { // Ensure aligned slices if (poolOffset & 0x7) { @@ -436,6 +442,7 @@ function allocate(size) { return new FastBuffer(); } if (size < (Buffer.poolSize >>> 1)) { + ensurePool(); if (size > (poolSize - poolOffset)) createPool(); const b = new FastBuffer(allocPool, poolOffset, size); @@ -462,6 +469,7 @@ function fromStringFast(string, ops) { if (length >= maxLength) return createFromString(string, ops, length); + ensurePool(); if (length > (poolSize - poolOffset)) createPool(); @@ -525,6 +533,7 @@ function fromArrayLike(obj) { if (obj.length <= 0) return new FastBuffer(); if (obj.length < (Buffer.poolSize >>> 1)) { + ensurePool(); if (obj.length > (poolSize - poolOffset)) createPool(); const b = new FastBuffer(allocPool, poolOffset, obj.length); diff --git a/test/parallel/test-buffer-pool-untransferable.js b/test/parallel/test-buffer-pool-untransferable.js index 596bb6b6c91422..00723d2692d808 100644 --- a/test/parallel/test-buffer-pool-untransferable.js +++ b/test/parallel/test-buffer-pool-untransferable.js @@ -21,3 +21,16 @@ assert.throws(() => port1.postMessage(a, [ a.buffer ]), { // Verify that the pool ArrayBuffer has not actually been transferred: assert.strictEqual(a.buffer, b.buffer); assert.strictEqual(a.length, length); + +if (typeof ArrayBuffer.prototype.transfer !== 'function') + common.skip('ArrayBuffer.prototype.transfer is not available'); + +// Regression test for https://github.com/nodejs/node/issues/61362 +const base64 = 'aGVsbG8='; // "hello" +const buf = Buffer.from(base64, 'base64'); +buf.buffer.transfer(); +assert.strictEqual(buf.buffer.byteLength, 0); +assert.doesNotThrow(() => { + const out = Buffer.from(base64, 'base64'); + assert.strictEqual(out.toString(), 'hello'); +});