fs: coerce FileHandle.read length like fs.read

Non-number length values reached node::fs::Read, which CHECKs
IsInt32() and aborts the process. Apply length |= 0 after defaulting,
matching fs.read and fs.readSync.

Signed-off-by: Xia Chao <236466140+bun-unsafe@users.noreply.github.com>
PR-URL: https://github.com/nodejs/node/pull/65521
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: LiviaMedeiros <livia@cirno.name>
This commit is contained in:
Xia Chao authored and GitHub committed 2026-09-18 05:27:15 +00:00
1 parent 0bf9e9f833
commit 32597d3d99
2 files changed
+23

No files matched your search

+1
View File
@@ -1462,6 +1462,7 @@ async function read(handle, bufferOrParams, offset, length, position) {
}
length ??= buffer.byteLength - offset;
length |= 0;
if (position == null) {
position = -1;
@@ -112,6 +112,27 @@ async function validateReadLength(len) {
}
}
async function validateReadLengthCoercedFromString() {
// Align with fs.read / fs.readSync (`length |= 0`). A non-number length
// must not reach node::fs::Read (CHECK args[3]->IsInt32()).
const buf = Buffer.alloc(4);
const filePath = fixtures.path('x.txt');
const fileHandle = await open(filePath, 'r');
try {
const { bytesRead } = await fileHandle.read(buf, 0, '1', 0);
assert.strictEqual(bytesRead, 1);
const { bytesRead: bytesReadOptions } = await fileHandle.read({
buffer: buf,
offset: 0,
length: '1',
position: 0,
});
assert.strictEqual(bytesReadOptions, 1);
} finally {
await fileHandle.close();
}
}
async function validateReadWithNoOptions(byte) {
const buf = Buffer.alloc(byte);
const filePath = fixtures.path('x.txt');
@@ -144,6 +165,7 @@ async function validateReadWithNoOptions(byte) {
await validateReadWithPositionZero();
await validateReadLength(0);
await validateReadLength(1);
await validateReadLengthCoercedFromString();
await validateReadWithNoOptions(0);
await validateReadWithNoOptions(1);
})().then(common.mustCall());