diff --git a/lib/fs.js b/lib/fs.js index 7b05750307c118..7168b7875498c5 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -85,7 +85,7 @@ const { } = require('internal/constants'); const { isUint32, - validateInt32, + validateInteger, validateUint32 } = require('internal/validators'); @@ -746,6 +746,7 @@ fs.truncate = function(path, len, callback) { len = 0; } + validateInteger(len, 'len'); callback = maybeCallback(callback); fs.open(path, 'r+', function(er, fd) { if (er) return callback(er); @@ -786,11 +787,7 @@ fs.ftruncate = function(fd, len = 0, callback) { len = 0; } validateUint32(fd, 'fd'); - // TODO(BridgeAR): This does not seem right. - // There does not seem to be any validation before and if there is any, it - // should work similar to validateUint32 or not have a upper cap at all. - // This applies to all usage of `validateInt32(len, 'len')`. - validateInt32(len, 'len'); + validateInteger(len, 'len'); len = Math.max(0, len); const req = new FSReqWrap(); req.oncomplete = makeCallback(callback); @@ -799,7 +796,7 @@ fs.ftruncate = function(fd, len = 0, callback) { fs.ftruncateSync = function(fd, len = 0) { validateUint32(fd, 'fd'); - validateInt32(len, 'len'); + validateInteger(len, 'len'); len = Math.max(0, len); const ctx = {}; binding.ftruncate(fd, len, undefined, ctx); diff --git a/lib/internal/fs/promises.js b/lib/internal/fs/promises.js index 4c0a256f5ad66c..d4dbffd850694e 100644 --- a/lib/internal/fs/promises.js +++ b/lib/internal/fs/promises.js @@ -34,7 +34,7 @@ const { } = require('internal/fs/utils'); const { isUint32, - validateInt32, + validateInteger, validateUint32 } = require('internal/validators'); const pathModule = require('path'); @@ -265,7 +265,7 @@ async function truncate(path, len = 0) { async function ftruncate(handle, len = 0) { validateFileHandle(handle); - validateInt32(len, 'len'); + validateInteger(len, 'len'); len = Math.max(0, len); return binding.ftruncate(handle.fd, len, kUsePromises); } diff --git a/lib/internal/validators.js b/lib/internal/validators.js index 556bfb2dc08f5f..aabe71ef33979a 100644 --- a/lib/internal/validators.js +++ b/lib/internal/validators.js @@ -13,7 +13,21 @@ function isUint32(value) { return value === (value >>> 0); } -function validateInt32(value, name) { +function validateInteger(value, name) { + let err; + + if (typeof value !== 'number') + err = new ERR_INVALID_ARG_TYPE(name, 'number', value); + else if (!Number.isSafeInteger(value)) + err = new ERR_OUT_OF_RANGE(name, 'an integer', value); + + if (err) { + Error.captureStackTrace(err, validateInteger); + throw err; + } +} + +function validateInt32(value, name, min = -2147483648, max = 2147483647) { if (!isInt32(value)) { let err; if (typeof value !== 'number') { @@ -53,6 +67,7 @@ function validateUint32(value, name, positive) { module.exports = { isInt32, isUint32, + validateInteger, validateInt32, validateUint32 }; diff --git a/test/parallel/test-fs-truncate.js b/test/parallel/test-fs-truncate.js index 2f8839583202d0..735385f61c5249 100644 --- a/test/parallel/test-fs-truncate.js +++ b/test/parallel/test-fs-truncate.js @@ -179,6 +179,16 @@ function testFtruncate(cb) { process.on('exit', () => fs.closeSync(fd)); ['', false, null, {}, []].forEach((input) => { + assert.throws( + () => fs.truncate(file5, input, common.mustNotCall()), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError [ERR_INVALID_ARG_TYPE]', + message: 'The "len" argument must be of type number. ' + + `Received type ${typeof input}` + } + ); + assert.throws( () => fs.ftruncate(fd, input), { @@ -191,6 +201,16 @@ function testFtruncate(cb) { }); [-1.5, 1.5].forEach((input) => { + assert.throws( + () => fs.truncate(file5, input), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError [ERR_OUT_OF_RANGE]', + message: 'The value of "len" is out of range. It must be ' + + `an integer. Received ${input}` + } + ); + assert.throws( () => fs.ftruncate(fd, input), { @@ -200,17 +220,14 @@ function testFtruncate(cb) { `an integer. Received ${input}` } ); - }); - // 2 ** 31 = 2147483648 - [2147483648, -2147483649].forEach((input) => { assert.throws( () => fs.ftruncate(fd, input), { code: 'ERR_OUT_OF_RANGE', name: 'RangeError [ERR_OUT_OF_RANGE]', message: 'The value of "len" is out of range. It must be ' + - `> -2147483649 && < 2147483648. Received ${input}` + `an integer. Received ${input}` } ); });