diff --git a/lib/fs.js b/lib/fs.js index a09c59a96d0..77c6998e531 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -162,14 +162,14 @@ function validateBuffer(buffer) { } } -function validateFd(fd) { +function validateLen(len) { let err; - if (!isUint32(fd)) - err = new errors.TypeError('ERR_INVALID_ARG_TYPE', 'fd', 'integer'); + if (!isInt32(len)) + err = new errors.TypeError('ERR_INVALID_ARG_TYPE', 'len', 'integer'); if (err !== undefined) { - Error.captureStackTrace(err, validateFd); + Error.captureStackTrace(err, validateLen); throw err; } } @@ -222,6 +222,18 @@ function validatePath(path, propName) { } } +function validateUint32(value, propName) { + let err; + + if (!isUint32(value)) + err = new errors.TypeError('ERR_INVALID_ARG_TYPE', propName, 'integer'); + + if (err !== undefined) { + Error.captureStackTrace(err, validateUint32); + throw err; + } +} + // Special case of `makeCallback()` that is specific to async `*stat()` calls as // an optimization, since the data passed back to the callback needs to be // transformed anyway. @@ -708,14 +720,14 @@ fs.readFileSync = function(path, options) { }; fs.close = function(fd, callback) { - validateFd(fd); + validateUint32(fd, 'fd'); const req = new FSReqWrap(); req.oncomplete = makeCallback(callback); binding.close(fd, req); }; fs.closeSync = function(fd) { - validateFd(fd); + validateUint32(fd, 'fd'); const ctx = {}; binding.close(fd, undefined, ctx); @@ -742,9 +754,7 @@ fs.open = function(path, flags, mode, callback_) { return; if (!nullCheck(path, callback)) return; validatePath(path); - - if (!isUint32(mode)) - throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'mode', 'integer'); + validateUint32(mode, 'mode'); const req = new FSReqWrap(); req.oncomplete = callback; @@ -760,16 +770,14 @@ fs.openSync = function(path, flags, mode) { handleError((path = getPathFromURL(path))); nullCheck(path); validatePath(path); - - if (!isUint32(mode)) - throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'mode', 'integer'); + validateUint32(mode, 'mode'); return binding.open(pathModule.toNamespacedPath(path), stringToFlags(flags), mode); }; fs.read = function(fd, buffer, offset, length, position, callback) { - validateFd(fd); + validateUint32(fd, 'fd'); validateBuffer(buffer); offset |= 0; @@ -801,7 +809,7 @@ Object.defineProperty(fs.read, internalUtil.customPromisifyArgs, { value: ['bytesRead', 'buffer'], enumerable: false }); fs.readSync = function(fd, buffer, offset, length, position) { - validateFd(fd); + validateUint32(fd, 'fd'); validateBuffer(buffer); offset |= 0; @@ -829,7 +837,7 @@ fs.write = function(fd, buffer, offset, length, position, callback) { callback(err, written || 0, buffer); } - validateFd(fd); + validateUint32(fd, 'fd'); const req = new FSReqWrap(); req.oncomplete = wrapper; @@ -869,7 +877,7 @@ Object.defineProperty(fs.write, internalUtil.customPromisifyArgs, // OR // fs.writeSync(fd, string[, position[, encoding]]); fs.writeSync = function(fd, buffer, offset, length, position) { - validateFd(fd); + validateUint32(fd, 'fd'); if (isUint8Array(buffer)) { if (position === undefined) position = null; @@ -968,9 +976,8 @@ fs.ftruncate = function(fd, len = 0, callback) { callback = len; len = 0; } - validateFd(fd); - if (!isInt32(len)) - throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'len', 'integer'); + validateUint32(fd, 'fd'); + validateLen(len); len = Math.max(0, len); const req = new FSReqWrap(); req.oncomplete = makeCallback(callback); @@ -978,9 +985,8 @@ fs.ftruncate = function(fd, len = 0, callback) { }; fs.ftruncateSync = function(fd, len = 0) { - validateFd(fd); - if (!isInt32(len)) - throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'len', 'integer'); + validateUint32(fd, 'fd'); + validateLen(len); len = Math.max(0, len); return binding.ftruncate(fd, len); }; @@ -1004,26 +1010,26 @@ fs.rmdirSync = function(path) { }; fs.fdatasync = function(fd, callback) { - validateFd(fd); + validateUint32(fd, 'fd'); const req = new FSReqWrap(); req.oncomplete = makeCallback(callback); binding.fdatasync(fd, req); }; fs.fdatasyncSync = function(fd) { - validateFd(fd); + validateUint32(fd, 'fd'); return binding.fdatasync(fd); }; fs.fsync = function(fd, callback) { - validateFd(fd); + validateUint32(fd, 'fd'); const req = new FSReqWrap(); req.oncomplete = makeCallback(callback); binding.fsync(fd, req); }; fs.fsyncSync = function(fd) { - validateFd(fd); + validateUint32(fd, 'fd'); return binding.fsync(fd); }; @@ -1036,8 +1042,7 @@ fs.mkdir = function(path, mode, callback) { validatePath(path); mode = modeNum(mode, 0o777); - if (!isUint32(mode)) - throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'mode', 'integer'); + validateUint32(mode, 'mode'); const req = new FSReqWrap(); req.oncomplete = callback; @@ -1049,8 +1054,7 @@ fs.mkdirSync = function(path, mode) { nullCheck(path); validatePath(path); mode = modeNum(mode, 0o777); - if (!isUint32(mode)) - throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'mode', 'integer'); + validateUint32(mode, 'mode'); return binding.mkdir(pathModule.toNamespacedPath(path), mode); }; @@ -1077,7 +1081,7 @@ fs.readdirSync = function(path, options) { }; fs.fstat = function(fd, callback) { - validateFd(fd); + validateUint32(fd, 'fd'); const req = new FSReqWrap(); req.oncomplete = makeStatsCallback(callback); binding.fstat(fd, req); @@ -1106,7 +1110,7 @@ fs.stat = function(path, callback) { }; fs.fstatSync = function(fd) { - validateFd(fd); + validateUint32(fd, 'fd'); binding.fstat(fd); return statsFromValues(); }; @@ -1273,9 +1277,8 @@ fs.unlinkSync = function(path) { fs.fchmod = function(fd, mode, callback) { mode = modeNum(mode); - validateFd(fd); - if (!isUint32(mode)) - throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'mode', 'integer'); + validateUint32(fd, 'fd'); + validateUint32(mode, 'mode'); if (mode < 0 || mode > 0o777) throw new errors.RangeError('ERR_OUT_OF_RANGE', 'mode'); @@ -1286,9 +1289,8 @@ fs.fchmod = function(fd, mode, callback) { fs.fchmodSync = function(fd, mode) { mode = modeNum(mode); - validateFd(fd); - if (!isUint32(mode)) - throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'mode', 'integer'); + validateUint32(fd, 'fd'); + validateUint32(mode, 'mode'); if (mode < 0 || mode > 0o777) throw new errors.RangeError('ERR_OUT_OF_RANGE', 'mode'); return binding.fchmod(fd, mode); @@ -1340,8 +1342,7 @@ fs.chmod = function(path, mode, callback) { validatePath(path); mode = modeNum(mode); - if (!isUint32(mode)) - throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'mode', 'integer'); + validateUint32(mode, 'mode'); const req = new FSReqWrap(); req.oncomplete = callback; @@ -1353,8 +1354,7 @@ fs.chmodSync = function(path, mode) { nullCheck(path); validatePath(path); mode = modeNum(mode); - if (!isUint32(mode)) - throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'mode', 'integer'); + validateUint32(mode, 'mode'); return binding.chmod(pathModule.toNamespacedPath(path), mode); }; @@ -1377,11 +1377,9 @@ if (constants.O_SYMLINK !== undefined) { } fs.fchown = function(fd, uid, gid, callback) { - validateFd(fd); - if (!isUint32(uid)) - throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'uid', 'integer'); - if (!isUint32(gid)) - throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'gid', 'integer'); + validateUint32(fd, 'fd'); + validateUint32(uid, 'uid'); + validateUint32(gid, 'gid'); const req = new FSReqWrap(); req.oncomplete = makeCallback(callback); @@ -1389,11 +1387,9 @@ fs.fchown = function(fd, uid, gid, callback) { }; fs.fchownSync = function(fd, uid, gid) { - validateFd(fd); - if (!isUint32(uid)) - throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'uid', 'integer'); - if (!isUint32(gid)) - throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'gid', 'integer'); + validateUint32(fd, 'fd'); + validateUint32(uid, 'uid'); + validateUint32(gid, 'gid'); return binding.fchown(fd, uid, gid); }; @@ -1405,10 +1401,8 @@ fs.chown = function(path, uid, gid, callback) { if (!nullCheck(path, callback)) return; validatePath(path); - if (!isUint32(uid)) - throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'uid', 'integer'); - if (!isUint32(gid)) - throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'gid', 'integer'); + validateUint32(uid, 'uid'); + validateUint32(gid, 'gid'); const req = new FSReqWrap(); req.oncomplete = callback; @@ -1419,10 +1413,8 @@ fs.chownSync = function(path, uid, gid) { handleError((path = getPathFromURL(path))); nullCheck(path); validatePath(path); - if (!isUint32(uid)) - throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'uid', 'integer'); - if (!isUint32(gid)) - throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'gid', 'integer'); + validateUint32(uid, 'uid'); + validateUint32(gid, 'gid'); return binding.chown(pathModule.toNamespacedPath(path), uid, gid); }; @@ -1477,7 +1469,7 @@ fs.utimesSync = function(path, atime, mtime) { }; fs.futimes = function(fd, atime, mtime, callback) { - validateFd(fd); + validateUint32(fd, 'fd'); atime = toUnixTimestamp(atime, 'atime'); mtime = toUnixTimestamp(mtime, 'mtime'); const req = new FSReqWrap(); @@ -1486,7 +1478,7 @@ fs.futimes = function(fd, atime, mtime, callback) { }; fs.futimesSync = function(fd, atime, mtime) { - validateFd(fd); + validateUint32(fd, 'fd'); atime = toUnixTimestamp(atime, 'atime'); mtime = toUnixTimestamp(mtime, 'mtime'); binding.futimes(fd, atime, mtime);