Skip to content

Commit ad1a533

Browse files
committed
webstreams: allow shared array buffer sources in writable adapter
Refs: #61913
1 parent 84ae06e commit ad1a533

File tree

3 files changed

+100
-5
lines changed

3 files changed

+100
-5
lines changed

lib/internal/webstreams/adapters.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ const {
5656
} = require('buffer');
5757

5858
const {
59-
isArrayBuffer,
59+
isAnyArrayBuffer,
6060
} = require('internal/util/types');
6161

6262
const {
@@ -230,11 +230,11 @@ function newWritableStreamFromStreamWritable(streamWritable, options = kEmptyObj
230230
start(c) { controller = c; },
231231

232232
write(chunk) {
233-
if (!streamWritable.writableObjectMode && isArrayBuffer(chunk)) {
234-
chunk = new Uint8Array(chunk);
235-
}
236233
try {
237234
options[kValidateChunk]?.(chunk);
235+
if (!streamWritable.writableObjectMode && isAnyArrayBuffer(chunk)) {
236+
chunk = new Uint8Array(chunk);
237+
}
238238
if (streamWritable.writableNeedDrain || !streamWritable.write(chunk)) {
239239
backpressurePromise = PromiseWithResolvers();
240240
return SafePromisePrototypeFinally(

lib/internal/webstreams/compression.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ function lazyZlib() {
4040
// Per the Compression Streams spec, chunks must be BufferSource
4141
// (ArrayBuffer or ArrayBufferView not backed by SharedArrayBuffer).
4242
function validateBufferSourceChunk(chunk) {
43-
if (isArrayBufferView(chunk) && isSharedArrayBuffer(chunk.buffer)) {
43+
if (isSharedArrayBuffer(isArrayBufferView(chunk) ? chunk.buffer : chunk)) {
4444
throw new ERR_INVALID_ARG_TYPE(
4545
'chunk',
4646
['ArrayBuffer', 'Buffer', 'TypedArray', 'DataView'],
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
'use strict';
2+
const common = require('../common');
3+
4+
const assert = require('assert');
5+
const { Buffer } = require('buffer');
6+
const { Duplex, Writable } = require('stream');
7+
const { suite, test } = require('node:test');
8+
9+
const ctors = [ArrayBuffer, SharedArrayBuffer];
10+
11+
suite('underlying Writable', () => {
12+
suite('in non-object mode', () => {
13+
for (const ctor of ctors) {
14+
test(`converts ${ctor.name} chunks`, async () => {
15+
const buffer = new ctor(4);
16+
const writable = new Writable({
17+
objectMode: false,
18+
write: common.mustCall((chunk, encoding, callback) => {
19+
assert(Buffer.isBuffer(chunk));
20+
assert.strictEqual(chunk.buffer, buffer);
21+
callback();
22+
}),
23+
});
24+
writable.on('error', common.mustNotCall());
25+
const writer = Writable.toWeb(writable).getWriter();
26+
await writer.write(buffer);
27+
});
28+
}
29+
});
30+
31+
suite('in object mode', () => {
32+
for (const ctor of ctors) {
33+
test(`passes through ${ctor.name} chunks`, async () => {
34+
const buffer = new ctor(4);
35+
const writable = new Writable({
36+
objectMode: true,
37+
write: common.mustCall((chunk, encoding, callback) => {
38+
assert(chunk instanceof ctor);
39+
assert.strictEqual(chunk, buffer);
40+
callback();
41+
}),
42+
});
43+
writable.on('error', common.mustNotCall());
44+
const writer = Writable.toWeb(writable).getWriter();
45+
await writer.write(buffer);
46+
});
47+
}
48+
});
49+
});
50+
51+
suite('underlying Duplex', () => {
52+
suite('in non-object mode', () => {
53+
for (const ctor of ctors) {
54+
test(`converts ${ctor.name} chunks`, async () => {
55+
const buffer = new ctor(4);
56+
const duplex = new Duplex({
57+
writableObjectMode: false,
58+
write: common.mustCall((chunk, encoding, callback) => {
59+
assert(Buffer.isBuffer(chunk));
60+
assert.strictEqual(chunk.buffer, buffer);
61+
callback();
62+
}),
63+
read() {
64+
this.push(null);
65+
},
66+
});
67+
duplex.on('error', common.mustNotCall());
68+
const writer = Duplex.toWeb(duplex).writable.getWriter();
69+
await writer.write(buffer);
70+
});
71+
}
72+
});
73+
74+
suite('in object mode', () => {
75+
for (const ctor of ctors) {
76+
test(`passes through ${ctor.name} chunks`, async () => {
77+
const buffer = new ctor(4);
78+
const duplex = new Duplex({
79+
writableObjectMode: true,
80+
write: common.mustCall((chunk, encoding, callback) => {
81+
assert(chunk instanceof ctor);
82+
assert.strictEqual(chunk, buffer);
83+
callback();
84+
}),
85+
read() {
86+
this.push(null);
87+
},
88+
});
89+
duplex.on('error', common.mustNotCall());
90+
const writer = Duplex.toWeb(duplex).writable.getWriter();
91+
await writer.write(buffer);
92+
});
93+
}
94+
});
95+
});

0 commit comments

Comments
 (0)