Skip to content

Commit 9c1098e

Browse files
committed
buffer: recreate pool after transfer
Fixes: #61362
1 parent eac00fa commit 9c1098e

File tree

2 files changed

+22
-0
lines changed

2 files changed

+22
-0
lines changed

lib/buffer.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,12 @@ function createPool() {
160160
}
161161
createPool();
162162

163+
function ensurePool() {
164+
// Recreate the pool if it was detached (e.g., via ArrayBuffer.prototype.transfer).
165+
if (allocPool.byteLength === 0)
166+
createPool();
167+
}
168+
163169
function alignPool() {
164170
// Ensure aligned slices
165171
if (poolOffset & 0x7) {
@@ -436,6 +442,7 @@ function allocate(size) {
436442
return new FastBuffer();
437443
}
438444
if (size < (Buffer.poolSize >>> 1)) {
445+
ensurePool();
439446
if (size > (poolSize - poolOffset))
440447
createPool();
441448
const b = new FastBuffer(allocPool, poolOffset, size);
@@ -462,6 +469,7 @@ function fromStringFast(string, ops) {
462469
if (length >= maxLength)
463470
return createFromString(string, ops, length);
464471

472+
ensurePool();
465473
if (length > (poolSize - poolOffset))
466474
createPool();
467475

@@ -525,6 +533,7 @@ function fromArrayLike(obj) {
525533
if (obj.length <= 0)
526534
return new FastBuffer();
527535
if (obj.length < (Buffer.poolSize >>> 1)) {
536+
ensurePool();
528537
if (obj.length > (poolSize - poolOffset))
529538
createPool();
530539
const b = new FastBuffer(allocPool, poolOffset, obj.length);

test/parallel/test-buffer-pool-untransferable.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,16 @@ assert.throws(() => port1.postMessage(a, [ a.buffer ]), {
2121
// Verify that the pool ArrayBuffer has not actually been transferred:
2222
assert.strictEqual(a.buffer, b.buffer);
2323
assert.strictEqual(a.length, length);
24+
25+
if (typeof ArrayBuffer.prototype.transfer !== 'function')
26+
common.skip('ArrayBuffer.prototype.transfer is not available');
27+
28+
// Regression test for https://github.com/nodejs/node/issues/61362
29+
const base64 = 'aGVsbG8='; // "hello"
30+
const buf = Buffer.from(base64, 'base64');
31+
buf.buffer.transfer();
32+
assert.strictEqual(buf.buffer.byteLength, 0);
33+
assert.doesNotThrow(() => {
34+
const out = Buffer.from(base64, 'base64');
35+
assert.strictEqual(out.toString(), 'hello');
36+
});

0 commit comments

Comments
 (0)