Skip to content

Commit

Permalink
stream: use Buffer.from when constructor is a Buffer
Browse files Browse the repository at this point in the history
When using BYOB streams, it's possible for the constructor in
readableByteStreamControllerConvertPullIntoDescriptor to be a node
Buffer. If it is, use `Buffer.from` over `new ctor`.

Fixes nodejs#49245

PR-URL: nodejs#49250
Reviewed-By: Debadree Chatterjee <[email protected]>
Reviewed-By: LiviaMedeiros <[email protected]>
Reviewed-By: Yagiz Nizipli <[email protected]>
  • Loading branch information
KhafraDev authored and alexfernandez committed Nov 1, 2023
1 parent 4e6d1b5 commit 6c0f789
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 0 deletions.
7 changes: 7 additions & 0 deletions lib/internal/webstreams/readablestream.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ const {
writableStreamDefaultWriterWrite,
} = require('internal/webstreams/writablestream');

const { Buffer } = require('buffer');

const assert = require('internal/assert');

const kCancel = Symbol('kCancel');
Expand Down Expand Up @@ -1904,6 +1906,11 @@ function readableByteStreamControllerConvertPullIntoDescriptor(desc) {
throw new ERR_INVALID_STATE.RangeError('The buffer size is invalid');
assert(!(bytesFilled % elementSize));
const transferredBuffer = transferArrayBuffer(buffer);

if (ctor === Buffer) {
return Buffer.from(transferredBuffer, byteOffset, bytesFilled / elementSize);
}

return new ctor(transferredBuffer, byteOffset, bytesFilled / elementSize);
}

Expand Down
62 changes: 62 additions & 0 deletions test/parallel/test-whatwg-readablebytestreambyob.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
'use strict';

const common = require('../common');

const {
open,
} = require('fs/promises');

const {
Buffer,
} = require('buffer');

class Source {
async start(controller) {
this.file = await open(__filename);
this.controller = controller;
}

async pull(controller) {
const byobRequest = controller.byobRequest;
const view = byobRequest.view;

const {
bytesRead,
} = await this.file.read({
buffer: view,
offset: view.byteOffset,
length: view.byteLength
});

if (bytesRead === 0) {
await this.file.close();
this.controller.close();
}

byobRequest.respond(bytesRead);
}

get type() { return 'bytes'; }

get autoAllocateChunkSize() { return 1024; }
}

(async () => {
const source = new Source();
const stream = new ReadableStream(source);

const { emitWarning } = process;

process.emitWarning = common.mustNotCall();

try {
const reader = stream.getReader({ mode: 'byob' });

let result;
do {
result = await reader.read(Buffer.alloc(100));
} while (!result.done);
} finally {
process.emitWarning = emitWarning;
}
})().then(common.mustCall());

0 comments on commit 6c0f789

Please sign in to comment.