diff --git a/lib/internal/fs/dir.js b/lib/internal/fs/dir.js index 32050f31ae6d..9c3963d33d92 100644 --- a/lib/internal/fs/dir.js +++ b/lib/internal/fs/dir.js @@ -5,6 +5,7 @@ const { ArrayPrototypeShift, FunctionPrototypeBind, ObjectDefineProperties, + ObjectHasOwn, PromiseReject, SymbolAsyncDispose, SymbolAsyncIterator, @@ -350,6 +351,12 @@ function opendir(path, options, callback) { encoding: 'utf8', }); + // Validate bufferSize before opening the directory. The Dir constructor + // validates it too, but an error thrown from opendirCallback can't be caught. + if (ObjectHasOwn(options, 'bufferSize')) { + validateUint32(options.bufferSize, 'options.bufferSize', true); + } + function opendirCallback(error, handle) { if (error) { callback(error); diff --git a/test/parallel/test-fs-opendir-invalid-buffersize.js b/test/parallel/test-fs-opendir-invalid-buffersize.js new file mode 100644 index 000000000000..53ab5bff5f9d --- /dev/null +++ b/test/parallel/test-fs-opendir-invalid-buffersize.js @@ -0,0 +1,36 @@ +'use strict'; + +// This tests that fs.opendir() and fs.promises.opendir() report an invalid +// bufferSize to the caller instead of throwing from an internal callback. + +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +for (const bufferSize of [-1, 0, 0.5, 1.5, Infinity, NaN]) { + const expected = { code: 'ERR_OUT_OF_RANGE', name: 'RangeError' }; + assert.throws( + () => fs.opendir(tmpdir.path, { bufferSize }, common.mustNotCall()), + expected, + ); + assert.rejects(fs.promises.opendir(tmpdir.path, { bufferSize }), expected) + .then(common.mustCall()); +} + +for (const bufferSize of ['', '1', null, undefined]) { + const expected = { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }; + assert.throws( + () => fs.opendir(tmpdir.path, { bufferSize }, common.mustNotCall()), + expected, + ); + assert.rejects(fs.promises.opendir(tmpdir.path, { bufferSize }), expected) + .then(common.mustCall()); +} + +// A valid bufferSize still opens the directory. +fs.opendir(tmpdir.path, { bufferSize: 1 }, common.mustSucceed((dir) => { + dir.closeSync(); +}));