mirror of
https://github.com/nodejs/node.git
synced 2026-10-14 10:26:26 -04:00
fs: fix async iterator partial writes
fix an issue where chunks might be partially written when using writeFile with an async iterator. PR-URL: https://github.com/nodejs/node/pull/38615 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
1 parent
61a67c1625
commit
3612229d44
2 files changed
+25
-4
No files matched your search
@@ -296,10 +296,16 @@ async function writeFileHandle(filehandle, data, signal, encoding) {
|
||||
if (isCustomIterable(data)) {
|
||||
for await (const buf of data) {
|
||||
checkAborted(signal);
|
||||
await write(
|
||||
filehandle, buf, undefined,
|
||||
isArrayBufferView(buf) ? buf.byteLength : encoding);
|
||||
checkAborted(signal);
|
||||
const toWrite =
|
||||
isArrayBufferView(buf) ? buf : Buffer.from(buf, encoding || 'utf8');
|
||||
let remaining = toWrite.byteLength;
|
||||
while (remaining > 0) {
|
||||
const writeSize = MathMin(kWriteFileMaxChunkSize, remaining);
|
||||
const { bytesWritten } = await write(
|
||||
filehandle, toWrite, toWrite.byteLength - remaining, writeSize);
|
||||
remaining -= bytesWritten;
|
||||
checkAborted(signal);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,14 @@ const iterable = {
|
||||
yield 'c';
|
||||
}
|
||||
};
|
||||
|
||||
const veryLargeBuffer = {
|
||||
expected: 'dogs running'.repeat(512 * 1024),
|
||||
*[Symbol.iterator]() {
|
||||
yield Buffer.from('dogs running'.repeat(512 * 1024), 'utf8');
|
||||
}
|
||||
};
|
||||
|
||||
function iterableWith(value) {
|
||||
return {
|
||||
*[Symbol.iterator]() {
|
||||
@@ -106,6 +114,12 @@ async function doWriteAsyncIterable() {
|
||||
assert.deepStrictEqual(data, asyncIterable.expected);
|
||||
}
|
||||
|
||||
async function doWriteAsyncLargeIterable() {
|
||||
await fsPromises.writeFile(dest, veryLargeBuffer);
|
||||
const data = fs.readFileSync(dest, 'utf-8');
|
||||
assert.deepStrictEqual(data, veryLargeBuffer.expected);
|
||||
}
|
||||
|
||||
async function doWriteInvalidValues() {
|
||||
await Promise.all(
|
||||
[42, 42n, {}, Symbol('42'), true, undefined, null, NaN].map((value) =>
|
||||
@@ -158,5 +172,6 @@ async function doReadWithEncoding() {
|
||||
await doWriteIterableWithEncoding();
|
||||
await doWriteBufferIterable();
|
||||
await doWriteAsyncIterable();
|
||||
await doWriteAsyncLargeIterable();
|
||||
await doWriteInvalidValues();
|
||||
})().then(common.mustCall());
|
||||
Reference in new issue
Block a user