From 1c1b8ae409368adee82ebe4edc090db570d21764 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Sat, 19 May 2018 21:07:16 -0400 Subject: [PATCH 1/2] lib: support ranges in validateInt32() This commit adds minimum and maximum value checks to the validateInt32() validator. PR-URL: https://github.com/nodejs/node/pull/20588 Fixes: https://github.com/nodejs/node/issues/20498 Reviewed-By: Joyee Cheung Reviewed-By: Weijia Wang Reviewed-By: Luigi Pinca Reviewed-By: James M Snell Reviewed-By: Matteo Collina --- lib/internal/validators.js | 10 +++++++--- test/parallel/test-fs-truncate.js | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/internal/validators.js b/lib/internal/validators.js index 21017ffc5ab791..7fea1bdf84c173 100644 --- a/lib/internal/validators.js +++ b/lib/internal/validators.js @@ -48,7 +48,8 @@ function validateAndMaskMode(value, name, def) { throw new ERR_INVALID_ARG_VALUE(name, value, modeDesc); } -function validateInt32(value, name) { +function validateInt32(value, name, min = -2147483648, max = 2147483647) { + // The defaults for min and max correspond to the limits of 32-bit integers. if (!isInt32(value)) { let err; if (typeof value !== 'number') { @@ -56,11 +57,14 @@ function validateInt32(value, name) { } else if (!Number.isInteger(value)) { err = new ERR_OUT_OF_RANGE(name, 'an integer', value); } else { - // 2 ** 31 === 2147483648 - err = new ERR_OUT_OF_RANGE(name, '> -2147483649 && < 2147483648', value); + err = new ERR_OUT_OF_RANGE(name, `>= ${min} && <= ${max}`, value); } Error.captureStackTrace(err, validateInt32); throw err; + } else if (value < min || value > max) { + const err = new ERR_OUT_OF_RANGE(name, `>= ${min} && <= ${max}`, value); + Error.captureStackTrace(err, validateInt32); + throw err; } } diff --git a/test/parallel/test-fs-truncate.js b/test/parallel/test-fs-truncate.js index 2f8839583202d0..eb469b8e271aed 100644 --- a/test/parallel/test-fs-truncate.js +++ b/test/parallel/test-fs-truncate.js @@ -210,7 +210,7 @@ function testFtruncate(cb) { 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}` + `>= -2147483648 && <= 2147483647. Received ${input}` } ); }); From 1ae184a85c05164b40933a5efc678cd9f008d2c4 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Sat, 19 May 2018 21:09:45 -0400 Subject: [PATCH 2/2] fs: improve fchmod{Sync} validation This commit validates the fd parameters to fs.fchmod{Sync} as int32s instead of uint32s because they are ints in the binding layer. PR-URL: https://github.com/nodejs/node/pull/20588 Fixes: https://github.com/nodejs/node/issues/20498 Reviewed-By: Joyee Cheung Reviewed-By: Weijia Wang Reviewed-By: Luigi Pinca Reviewed-By: James M Snell Reviewed-By: Matteo Collina --- lib/fs.js | 4 ++-- test/parallel/test-fs-fchmod.js | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/lib/fs.js b/lib/fs.js index 6b0a88fac7a92d..f46eabf9a07d07 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -1057,7 +1057,7 @@ fs.unlinkSync = function(path) { }; fs.fchmod = function(fd, mode, callback) { - validateUint32(fd, 'fd'); + validateInt32(fd, 'fd', 0); mode = validateAndMaskMode(mode, 'mode'); callback = makeCallback(callback); @@ -1067,7 +1067,7 @@ fs.fchmod = function(fd, mode, callback) { }; fs.fchmodSync = function(fd, mode) { - validateUint32(fd, 'fd'); + validateInt32(fd, 'fd', 0); mode = validateAndMaskMode(mode, 'mode'); const ctx = {}; binding.fchmod(fd, mode, undefined, ctx); diff --git a/test/parallel/test-fs-fchmod.js b/test/parallel/test-fs-fchmod.js index df7748538a5cc4..4f6350e63c241a 100644 --- a/test/parallel/test-fs-fchmod.js +++ b/test/parallel/test-fs-fchmod.js @@ -35,12 +35,21 @@ const fs = require('fs'); const errObj = { code: 'ERR_OUT_OF_RANGE', name: 'RangeError [ERR_OUT_OF_RANGE]', - message: 'The value of "fd" is out of range. It must be >= 0 && < ' + - `${2 ** 32}. Received ${input}` + message: 'The value of "fd" is out of range. It must be >= 0 && <= ' + + `2147483647. Received ${input}` }; assert.throws(() => fs.fchmod(input), errObj); assert.throws(() => fs.fchmodSync(input), errObj); - errObj.message = errObj.message.replace('fd', 'mode'); +}); + +[-1, 2 ** 32].forEach((input) => { + const errObj = { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError [ERR_OUT_OF_RANGE]', + message: 'The value of "mode" is out of range. It must be >= 0 && < ' + + `4294967296. Received ${input}` + }; + assert.throws(() => fs.fchmod(1, input), errObj); assert.throws(() => fs.fchmodSync(1, input), errObj); });