From 82eb459e3f5bab86c6aa75eae41cb51da1c6e2f6 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Sun, 26 Nov 2017 16:53:33 -0800 Subject: [PATCH] fs: move type checking for fs.fchown to js PR-URL: https://github.com/nodejs/node/pull/17334 Reviewed-By: Refael Ackermann Reviewed-By: Timothy Gu Reviewed-By: Jon Moss Reviewed-By: Anna Henningsen Reviewed-By: Joyee Cheung Reviewed-By: Matteo Collina --- lib/fs.js | 28 +++++++- src/node_file.cc | 16 +---- test/parallel/test-fs-fchown.js | 110 ++++++++++++++++++++++++++++++++ 3 files changed, 140 insertions(+), 14 deletions(-) create mode 100644 test/parallel/test-fs-fchown.js 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' + } +);