Skip to content

Commit 7a728e1

Browse files
committed
stream: validate writevSync chunks before queuing
Ensure writevSync() validates every chunk before handing the batch to the push queue. Invalid chunks now throw ERR_INVALID_ARG_TYPE without leaving data readable from the failed write. Signed-off-by: Kamat, Trivikram <16024985+trivikr@users.noreply.github.com> Assisted-by: openai:gpt-5.5
1 parent b59def5 commit 7a728e1

2 files changed

Lines changed: 26 additions & 4 deletions

File tree

lib/internal/streams/iter/utils.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -190,15 +190,14 @@ function toUint8Array(chunk) {
190190
}
191191

192192
/**
193-
* Check if all chunks in an array are already Uint8Array (no strings).
194-
* Short-circuits on the first string found.
193+
* Check if all chunks in an array are already Uint8Array.
194+
* Short-circuits on the first non-Uint8Array chunk found.
195195
* @param {Array<Uint8Array|string>} chunks
196196
* @returns {boolean}
197197
*/
198198
function allUint8Array(chunks) {
199-
// Ok, well, kind of. This is more a check for "no strings"...
200199
for (let i = 0; i < chunks.length; i++) {
201-
if (typeof chunks[i] === 'string') return false;
200+
if (!isUint8Array(chunks[i])) return false;
202201
}
203202
return true;
204203
}

test/parallel/test-stream-iter-push-writer.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,28 @@ async function testWritevSync() {
171171
assert.strictEqual(result, 'hello');
172172
}
173173

174+
async function testWritevSyncInvalidChunkDoesNotQueue() {
175+
const { writer, readable } = push({ highWaterMark: 10 });
176+
177+
assert.throws(
178+
() => writer.writevSync([1]),
179+
{ code: 'ERR_INVALID_ARG_TYPE' },
180+
);
181+
182+
const iter = readable[Symbol.asyncIterator]();
183+
const next = iter.next();
184+
const result = await Promise.race([
185+
next.then(() => 'resolved'),
186+
new Promise((resolve) => setImmediate(resolve, 'pending')),
187+
]);
188+
assert.strictEqual(result, 'pending');
189+
190+
writer.endSync();
191+
const end = await next;
192+
assert.strictEqual(end.value, undefined);
193+
assert.strictEqual(end.done, true);
194+
}
195+
174196
async function testWritevMixedTypes() {
175197
const { writer, readable } = push({ highWaterMark: 10 });
176198
// Mix strings and Uint8Arrays
@@ -494,6 +516,7 @@ Promise.all([
494516
testOndrainRejectsOnConsumerThrow(),
495517
testWritev(),
496518
testWritevSync(),
519+
testWritevSyncInvalidChunkDoesNotQueue(),
497520
testWritevMixedTypes(),
498521
testWriteAfterEnd(),
499522
testWriteAfterFail(),

0 commit comments

Comments
 (0)