diff --git a/lib/fs.js b/lib/fs.js index c105f5fb3aa7b0..f13488ba0e62e4 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -1249,12 +1249,38 @@ if (constants.O_SYMLINK !== undefined) { } fs.fchown = function(fd, uid, gid, callback) { - var req = new FSReqWrap(); + if (!Number.isInteger(fd)) + throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'fd', 'number'); + if (fd < 0 || fd > 0xFFFFFFFF) + throw new errors.RangeError('ERR_OUT_OF_RANGE', 'fd'); + if (!Number.isInteger(uid)) + throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'uid', 'number'); + if (uid < 0) + throw new errors.RangeError('ERR_OUT_OF_RANGE', 'uid'); + if (!Number.isInteger(gid)) + throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'gid', 'number'); + if (gid < 0) + throw new errors.RangeError('ERR_OUT_OF_RANGE', 'gid'); + + const req = new FSReqWrap(); req.oncomplete = makeCallback(callback); binding.fchown(fd, uid, gid, req); }; fs.fchownSync = function(fd, uid, gid) { + if (!Number.isInteger(fd)) + throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'fd', 'number'); + if (fd < 0 || fd > 0xFFFFFFFF) + throw new errors.RangeError('ERR_OUT_OF_RANGE', 'fd'); + if (!Number.isInteger(uid)) + throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'uid', 'number'); + if (uid < 0) + throw new errors.RangeError('ERR_OUT_OF_RANGE', 'uid'); + if (!Number.isInteger(gid)) + throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'gid', 'number'); + if (gid < 0) + throw new errors.RangeError('ERR_OUT_OF_RANGE', 'gid'); + return binding.fchown(fd, uid, gid); }; diff --git a/src/node_file.cc b/src/node_file.cc index 2acac8c8f8bdfb..0d90df0e954ee8 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -1306,19 +1306,9 @@ static void Chown(const FunctionCallbackInfo& args) { static void FChown(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); - int len = args.Length(); - if (len < 1) - return TYPE_ERROR("fd required"); - if (len < 2) - return TYPE_ERROR("uid required"); - if (len < 3) - return TYPE_ERROR("gid required"); - if (!args[0]->IsInt32()) - return TYPE_ERROR("fd must be an int"); - if (!args[1]->IsUint32()) - return TYPE_ERROR("uid must be an unsigned int"); - if (!args[2]->IsUint32()) - return TYPE_ERROR("gid must be an unsigned int"); + CHECK(args[0]->IsInt32()); + CHECK(args[1]->IsUint32()); + CHECK(args[2]->IsUint32()); int fd = args[0]->Int32Value(); uv_uid_t uid = static_cast(args[1]->Uint32Value()); diff --git a/test/parallel/test-fs-fchown.js b/test/parallel/test-fs-fchown.js new file mode 100644 index 00000000000000..2e75c6b909bfbc --- /dev/null +++ b/test/parallel/test-fs-fchown.js @@ -0,0 +1,110 @@ +'use strict'; + +const common = require('../common'); +const fs = require('fs'); + +['', false, null, undefined, {}, []].forEach((i) => { + common.expectsError( + () => fs.fchown(i), + { + code: 'ERR_INVALID_ARG_TYPE', + type: TypeError, + message: 'The "fd" argument must be of type number' + } + ); + common.expectsError( + () => fs.fchownSync(i), + { + code: 'ERR_INVALID_ARG_TYPE', + type: TypeError, + message: 'The "fd" argument must be of type number' + } + ); + + common.expectsError( + () => fs.fchown(1, i), + { + code: 'ERR_INVALID_ARG_TYPE', + type: TypeError, + message: 'The "uid" argument must be of type number' + } + ); + common.expectsError( + () => fs.fchownSync(1, i), + { + code: 'ERR_INVALID_ARG_TYPE', + type: TypeError, + message: 'The "uid" argument must be of type number' + } + ); + + common.expectsError( + () => fs.fchown(1, 1, i), + { + code: 'ERR_INVALID_ARG_TYPE', + type: TypeError, + message: 'The "gid" argument must be of type number' + } + ); + common.expectsError( + () => fs.fchownSync(1, 1, i), + { + code: 'ERR_INVALID_ARG_TYPE', + type: TypeError, + message: 'The "gid" argument must be of type number' + } + ); +}); + +[-1, 0xFFFFFFFF + 1].forEach((i) => { + common.expectsError( + () => fs.fchown(i), + { + code: 'ERR_OUT_OF_RANGE', + type: RangeError, + message: 'The "fd" argument is out of range' + } + ); + common.expectsError( + () => fs.fchownSync(i), + { + code: 'ERR_OUT_OF_RANGE', + type: RangeError, + message: 'The "fd" argument is out of range' + } + ); +}); + +common.expectsError( + () => fs.fchown(1, -1), + { + code: 'ERR_OUT_OF_RANGE', + type: RangeError, + message: 'The "uid" argument is out of range' + } +); +common.expectsError( + () => fs.fchownSync(1, -1), + { + code: 'ERR_OUT_OF_RANGE', + type: RangeError, + message: 'The "uid" argument is out of range' + } +); + +common.expectsError( + () => fs.fchown(1, 1, -1), + { + code: 'ERR_OUT_OF_RANGE', + type: RangeError, + message: 'The "gid" argument is out of range' + } +); +common.expectsError( + () => fs.fchownSync(1, 1, -1), + { + code: 'ERR_OUT_OF_RANGE', + type: RangeError, + message: 'The "gid" argument is out of range' + } +);