Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions lib/internal/webstreams/adapters.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const {
} = require('buffer');

const {
isArrayBuffer,
isAnyArrayBuffer,
} = require('internal/util/types');

const {
Expand Down Expand Up @@ -230,11 +230,11 @@ function newWritableStreamFromStreamWritable(streamWritable, options = kEmptyObj
start(c) { controller = c; },

write(chunk) {
if (!streamWritable.writableObjectMode && isArrayBuffer(chunk)) {
chunk = new Uint8Array(chunk);
}
try {
options[kValidateChunk]?.(chunk);
if (!streamWritable.writableObjectMode && isAnyArrayBuffer(chunk)) {
chunk = new Uint8Array(chunk);
}
Comment on lines +235 to +237
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This operation can throw (if chunk is a detached array buffer), so should be within the try/catch block.

if (streamWritable.writableNeedDrain || !streamWritable.write(chunk)) {
backpressurePromise = PromiseWithResolvers();
return SafePromisePrototypeFinally(
Expand Down
2 changes: 1 addition & 1 deletion lib/internal/webstreams/compression.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ function lazyZlib() {
// Per the Compression Streams spec, chunks must be BufferSource
// (ArrayBuffer or ArrayBufferView not backed by SharedArrayBuffer).
function validateBufferSourceChunk(chunk) {
if (isArrayBufferView(chunk) && isSharedArrayBuffer(chunk.buffer)) {
if (isSharedArrayBuffer(isArrayBufferView(chunk) ? chunk.buffer : chunk)) {
throw new ERR_INVALID_ARG_TYPE(
'chunk',
['ArrayBuffer', 'Buffer', 'TypedArray', 'DataView'],
Expand Down
95 changes: 95 additions & 0 deletions test/parallel/test-webstreams-adapters-writable-buffer-sources.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
'use strict';
const common = require('../common');

const assert = require('assert');
const { Buffer } = require('buffer');
const { Duplex, Writable } = require('stream');
const { suite, test } = require('node:test');

const ctors = [ArrayBuffer, SharedArrayBuffer];

suite('underlying Writable', () => {
suite('in non-object mode', () => {
for (const ctor of ctors) {
test(`converts ${ctor.name} chunks`, async () => {
const buffer = new ctor(4);
const writable = new Writable({
objectMode: false,
write: common.mustCall((chunk, encoding, callback) => {
assert(Buffer.isBuffer(chunk));
assert.strictEqual(chunk.buffer, buffer);
callback();
}),
});
writable.on('error', common.mustNotCall());
const writer = Writable.toWeb(writable).getWriter();
await writer.write(buffer);
});
}
});

suite('in object mode', () => {
for (const ctor of ctors) {
test(`passes through ${ctor.name} chunks`, async () => {
const buffer = new ctor(4);
const writable = new Writable({
objectMode: true,
write: common.mustCall((chunk, encoding, callback) => {
assert(chunk instanceof ctor);
assert.strictEqual(chunk, buffer);
callback();
}),
});
writable.on('error', common.mustNotCall());
const writer = Writable.toWeb(writable).getWriter();
await writer.write(buffer);
});
}
});
});

suite('underlying Duplex', () => {
suite('in non-object mode', () => {
for (const ctor of ctors) {
test(`converts ${ctor.name} chunks`, async () => {
const buffer = new ctor(4);
const duplex = new Duplex({
writableObjectMode: false,
write: common.mustCall((chunk, encoding, callback) => {
assert(Buffer.isBuffer(chunk));
assert.strictEqual(chunk.buffer, buffer);
callback();
}),
read() {
this.push(null);
},
});
duplex.on('error', common.mustNotCall());
const writer = Duplex.toWeb(duplex).writable.getWriter();
await writer.write(buffer);
});
}
});

suite('in object mode', () => {
for (const ctor of ctors) {
test(`passes through ${ctor.name} chunks`, async () => {
const buffer = new ctor(4);
const duplex = new Duplex({
writableObjectMode: true,
write: common.mustCall((chunk, encoding, callback) => {
assert(chunk instanceof ctor);
assert.strictEqual(chunk, buffer);
callback();
}),
read() {
this.push(null);
},
});
duplex.on('error', common.mustNotCall());
const writer = Duplex.toWeb(duplex).writable.getWriter();
await writer.write(buffer);
});
}
});
});
Loading