diff options
author | Michaƫl Zasso <targos@protonmail.com> | 2018-04-12 11:54:19 +0200 |
---|---|---|
committer | Ruben Bridgewater <ruben@bridgewater.de> | 2018-04-26 19:42:55 +0200 |
commit | 2fd248f639981c72794efef397dfae5263ebdff5 (patch) | |
tree | 1197085154c2f2d1565ffa89099db66f7fc29833 /lib | |
parent | e8361287030fbaa773761bb3798d45903bb160f6 (diff) | |
download | android-node-v8-2fd248f639981c72794efef397dfae5263ebdff5.tar.gz android-node-v8-2fd248f639981c72794efef397dfae5263ebdff5.tar.bz2 android-node-v8-2fd248f639981c72794efef397dfae5263ebdff5.zip |
process: migrate methods to throw errors with code
Migrate some methods from node.cc to JS in order to properly throw
errors with codes.
PR-URL: https://github.com/nodejs/node/pull/19973
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/internal/bootstrap/node.js | 1 | ||||
-rw-r--r-- | lib/internal/errors.js | 1 | ||||
-rw-r--r-- | lib/internal/process/methods.js | 137 |
3 files changed, 139 insertions, 0 deletions
diff --git a/lib/internal/bootstrap/node.js b/lib/internal/bootstrap/node.js index f9bed03d26..5993cc71f7 100644 --- a/lib/internal/bootstrap/node.js +++ b/lib/internal/bootstrap/node.js @@ -41,6 +41,7 @@ NativeModule.require('internal/process/warning').setup(); NativeModule.require('internal/process/next_tick').setup(); NativeModule.require('internal/process/stdio').setup(); + NativeModule.require('internal/process/methods').setup(); const perf = process.binding('performance'); const { diff --git a/lib/internal/errors.js b/lib/internal/errors.js index e7eb3bd133..882e40af88 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -1017,6 +1017,7 @@ E('ERR_UNHANDLED_ERROR', if (err === undefined) return msg; return `${msg} (${err})`; }, Error); +E('ERR_UNKNOWN_CREDENTIAL', '%s identifier does not exist: %s', Error); E('ERR_UNKNOWN_ENCODING', 'Unknown encoding: %s', TypeError); // This should probably be a `TypeError`. diff --git a/lib/internal/process/methods.js b/lib/internal/process/methods.js new file mode 100644 index 0000000000..503fd317f6 --- /dev/null +++ b/lib/internal/process/methods.js @@ -0,0 +1,137 @@ +'use strict'; + +const { + ERR_INVALID_ARG_TYPE, + ERR_INVALID_ARG_VALUE, + ERR_UNKNOWN_CREDENTIAL +} = require('internal/errors').codes; +const { + validateUint32 +} = require('internal/validators'); + +function setupProcessMethods() { + // Non-POSIX platforms like Windows don't have certain methods. + if (process.setgid !== undefined) { + setupPosixMethods(); + } + + const { + chdir: _chdir, + umask: _umask, + } = process; + + process.chdir = chdir; + process.umask = umask; + + function chdir(directory) { + if (typeof directory !== 'string') { + throw new ERR_INVALID_ARG_TYPE('directory', 'string', directory); + } + return _chdir(directory); + } + + const octalReg = /^[0-7]+$/; + function umask(mask) { + if (typeof mask === 'undefined') { + return _umask(mask); + } + + if (typeof mask === 'number') { + validateUint32(mask, 'mask'); + return _umask(mask); + } + + if (typeof mask === 'string') { + if (!octalReg.test(mask)) { + throw new ERR_INVALID_ARG_VALUE('mask', mask, + 'must be an octal string'); + } + const octal = Number.parseInt(mask, 8); + validateUint32(octal, 'mask'); + return _umask(octal); + } + + throw new ERR_INVALID_ARG_TYPE('mask', ['number', 'string', 'undefined'], + mask); + } +} + +function setupPosixMethods() { + const { + initgroups: _initgroups, + setegid: _setegid, + seteuid: _seteuid, + setgid: _setgid, + setuid: _setuid, + setgroups: _setgroups + } = process; + + process.initgroups = initgroups; + process.setegid = setegid; + process.seteuid = seteuid; + process.setgid = setgid; + process.setuid = setuid; + process.setgroups = setgroups; + + function initgroups(user, extraGroup) { + validateId(user, 'user'); + validateId(extraGroup, 'extraGroup'); + // Result is 0 on success, 1 if user is unknown, 2 if group is unknown. + const result = _initgroups(user, extraGroup); + if (result === 1) { + throw new ERR_UNKNOWN_CREDENTIAL('User', user); + } else if (result === 2) { + throw new ERR_UNKNOWN_CREDENTIAL('Group', extraGroup); + } + } + + function setegid(id) { + return execId(id, 'Group', _setegid); + } + + function seteuid(id) { + return execId(id, 'User', _seteuid); + } + + function setgid(id) { + return execId(id, 'Group', _setgid); + } + + function setuid(id) { + return execId(id, 'User', _setuid); + } + + function setgroups(groups) { + if (!Array.isArray(groups)) { + throw new ERR_INVALID_ARG_TYPE('groups', 'Array', groups); + } + for (var i = 0; i < groups.length; i++) { + validateId(groups[i], `groups[${i}]`); + } + // Result is 0 on success. A positive integer indicates that the + // corresponding group was not found. + const result = _setgroups(groups); + if (result > 0) { + throw new ERR_UNKNOWN_CREDENTIAL('Group', groups[result - 1]); + } + } + + function execId(id, type, method) { + validateId(id, 'id'); + // Result is 0 on success, 1 if credential is unknown. + const result = method(id); + if (result === 1) { + throw new ERR_UNKNOWN_CREDENTIAL(type, id); + } + } + + function validateId(id, name) { + if (typeof id === 'number') { + validateUint32(id, name); + } else if (typeof id !== 'string') { + throw new ERR_INVALID_ARG_TYPE(name, ['number', 'string'], id); + } + } +} + +exports.setup = setupProcessMethods; |