diff --git a/lib/internal/fs/promises.js b/lib/internal/fs/promises.js index 43956dae3f4d18..54a69aa02679e0 100644 --- a/lib/internal/fs/promises.js +++ b/lib/internal/fs/promises.js @@ -31,7 +31,6 @@ const { validatePath } = require('internal/fs/utils'); const { - isUint32, validateMode, validateInteger, validateUint32 @@ -211,7 +210,7 @@ async function read(handle, buffer, offset, length, position) { validateOffsetLengthRead(offset, length, buffer.length); - if (!isUint32(position)) + if (!Number.isSafeInteger(position)) position = -1; const bytesRead = (await binding.read(handle.fd, buffer, offset, length, diff --git a/test/parallel/test-fs-promises-file-handle-read.js b/test/parallel/test-fs-promises-file-handle-read.js index a397b0e260aff4..621e63c075a256 100644 --- a/test/parallel/test-fs-promises-file-handle-read.js +++ b/test/parallel/test-fs-promises-file-handle-read.js @@ -8,6 +8,7 @@ const common = require('../common'); const fs = require('fs'); const { open } = fs.promises; const path = require('path'); +const fixtures = require('../common/fixtures'); const tmpdir = require('../common/tmpdir'); const assert = require('assert'); const tmpDir = tmpdir.path; @@ -40,6 +41,19 @@ async function validateEmptyRead() { assert.deepStrictEqual(buffer.length, readAsyncHandle.bytesRead); } +async function validateLargeRead() { + // Reading beyond file length (3 in this case) should return no data. + // This is a test for a bug where reads > uint32 would return data + // from the current position in the file. + const filePath = fixtures.path('x.txt'); + const fileHandle = await open(filePath, 'r'); + const pos = 0xffffffff + 1; // max-uint32 + 1 + const readHandle = await fileHandle.read(Buffer.alloc(1), 0, 1, pos); + + assert.strictEqual(readHandle.bytesRead, 0); +} + validateRead() .then(validateEmptyRead) + .then(validateLargeRead) .then(common.mustCall());