fs: extract out validatePath function

PR-URL: https://github.com/nodejs/node/pull/17682
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
This commit is contained in:
Jon Moss 2017-12-22 18:42:21 -05:00 committed by Joyee Cheung
parent 300ea7396f
commit 46e1d69bd1
No known key found for this signature in database
GPG Key ID: F586868AAD831D0C

237
lib/fs.js
View File

@ -204,6 +204,24 @@ function validateOffsetLengthWrite(offset, length, byteLength) {
}
}
function validatePath(path, propName) {
let err;
if (propName === undefined) {
propName = 'path';
}
if (typeof path !== 'string' && !isUint8Array(path)) {
err = new errors.TypeError('ERR_INVALID_ARG_TYPE', propName,
['string', 'Buffer', 'URL']);
}
if (err !== undefined) {
Error.captureStackTrace(err, validatePath);
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.
@ -351,10 +369,7 @@ fs.access = function(path, mode, callback) {
if (handleError((path = getPathFromURL(path)), callback))
return;
if (typeof path !== 'string' && !(path instanceof Buffer)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
['string', 'Buffer', 'URL']);
}
validatePath(path);
if (!nullCheck(path, callback))
return;
@ -367,12 +382,7 @@ fs.access = function(path, mode, callback) {
fs.accessSync = function(path, mode) {
handleError((path = getPathFromURL(path)));
if (typeof path !== 'string' && !(path instanceof Buffer)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
['string', 'Buffer', 'URL']);
}
validatePath(path);
nullCheck(path);
if (mode === undefined)
@ -391,10 +401,7 @@ fs.accessSync = function(path, mode) {
fs.exists = function(path, callback) {
if (handleError((path = getPathFromURL(path)), cb))
return;
if (typeof path !== 'string' && !(path instanceof Buffer)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
['string', 'Buffer', 'URL']);
}
validatePath(path);
if (!nullCheck(path, cb)) return;
var req = new FSReqWrap();
req.oncomplete = cb;
@ -416,7 +423,9 @@ Object.defineProperty(fs.exists, internalUtil.promisify.custom, {
fs.existsSync = function(path) {
try {
handleError((path = getPathFromURL(path)));
if (typeof path !== 'string' && !(path instanceof Buffer)) {
try {
validatePath(path);
} catch (e) {
return false;
}
nullCheck(path);
@ -447,11 +456,10 @@ fs.readFile = function(path, options, callback) {
req.oncomplete(null, path);
});
return;
} else if (typeof path !== 'string' && !(path instanceof Buffer)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
['string', 'Buffer', 'URL']);
}
validatePath(path);
binding.open(pathModule.toNamespacedPath(path),
stringToFlags(options.flag || 'r'),
0o666,
@ -733,11 +741,7 @@ fs.open = function(path, flags, mode, callback_) {
if (handleError((path = getPathFromURL(path)), callback))
return;
if (!nullCheck(path, callback)) return;
if (typeof path !== 'string' && !isUint8Array(path)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
['string', 'Buffer', 'URL']);
}
validatePath(path);
if (!isUint32(mode))
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'mode', 'integer');
@ -755,10 +759,7 @@ fs.openSync = function(path, flags, mode) {
mode = modeNum(mode, 0o666);
handleError((path = getPathFromURL(path)));
nullCheck(path);
if (typeof path !== 'string' && !isUint8Array(path)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
['string', 'Buffer', 'URL']);
}
validatePath(path);
if (!isUint32(mode))
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'mode', 'integer');
@ -896,15 +897,8 @@ fs.rename = function(oldPath, newPath, callback) {
if (!nullCheck(oldPath, callback)) return;
if (!nullCheck(newPath, callback)) return;
if (typeof oldPath !== 'string' && !isUint8Array(oldPath)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'oldPath',
['string', 'Buffer', 'URL']);
}
if (typeof newPath !== 'string' && !isUint8Array(newPath)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'newPath',
['string', 'Buffer', 'URL']);
}
validatePath(oldPath, 'oldPath');
validatePath(newPath, 'newPath');
const req = new FSReqWrap();
req.oncomplete = callback;
binding.rename(pathModule.toNamespacedPath(oldPath),
@ -917,14 +911,8 @@ fs.renameSync = function(oldPath, newPath) {
handleError((newPath = getPathFromURL(newPath)));
nullCheck(oldPath);
nullCheck(newPath);
if (typeof oldPath !== 'string' && !isUint8Array(oldPath)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'oldPath',
['string', 'Buffer', 'URL']);
}
if (typeof newPath !== 'string' && !isUint8Array(newPath)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'newPath',
['string', 'Buffer', 'URL']);
}
validatePath(oldPath, 'oldPath');
validatePath(newPath, 'newPath');
return binding.rename(pathModule.toNamespacedPath(oldPath),
pathModule.toNamespacedPath(newPath));
};
@ -1002,10 +990,7 @@ fs.rmdir = function(path, callback) {
if (handleError((path = getPathFromURL(path)), callback))
return;
if (!nullCheck(path, callback)) return;
if (typeof path !== 'string' && !isUint8Array(path)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
['string', 'Buffer', 'URL']);
}
validatePath(path);
const req = new FSReqWrap();
req.oncomplete = callback;
binding.rmdir(pathModule.toNamespacedPath(path), req);
@ -1014,10 +999,7 @@ fs.rmdir = function(path, callback) {
fs.rmdirSync = function(path) {
handleError((path = getPathFromURL(path)));
nullCheck(path);
if (typeof path !== 'string' && !isUint8Array(path)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
['string', 'Buffer', 'URL']);
}
validatePath(path);
return binding.rmdir(pathModule.toNamespacedPath(path));
};
@ -1052,10 +1034,7 @@ fs.mkdir = function(path, mode, callback) {
return;
if (!nullCheck(path, callback)) return;
if (typeof path !== 'string' && !isUint8Array(path)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
['string', 'Buffer', 'URL']);
}
validatePath(path);
mode = modeNum(mode, 0o777);
if (!isUint32(mode))
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'mode', 'integer');
@ -1068,10 +1047,7 @@ fs.mkdir = function(path, mode, callback) {
fs.mkdirSync = function(path, mode) {
handleError((path = getPathFromURL(path)));
nullCheck(path);
if (typeof path !== 'string' && !isUint8Array(path)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
['string', 'Buffer', 'URL']);
}
validatePath(path);
mode = modeNum(mode, 0o777);
if (!isUint32(mode))
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'mode', 'integer');
@ -1085,10 +1061,7 @@ fs.readdir = function(path, options, callback) {
return;
if (!nullCheck(path, callback)) return;
if (typeof path !== 'string' && !isUint8Array(path)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
['string', 'Buffer', 'URL']);
}
validatePath(path);
const req = new FSReqWrap();
req.oncomplete = callback;
@ -1099,10 +1072,7 @@ fs.readdirSync = function(path, options) {
options = getOptions(options, {});
handleError((path = getPathFromURL(path)));
nullCheck(path);
if (typeof path !== 'string' && !isUint8Array(path)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
['string', 'Buffer', 'URL']);
}
validatePath(path);
return binding.readdir(pathModule.toNamespacedPath(path), options.encoding);
};
@ -1118,10 +1088,7 @@ fs.lstat = function(path, callback) {
if (handleError((path = getPathFromURL(path)), callback))
return;
if (!nullCheck(path, callback)) return;
if (typeof path !== 'string' && !isUint8Array(path)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
['string', 'Buffer', 'URL']);
}
validatePath(path);
const req = new FSReqWrap();
req.oncomplete = callback;
binding.lstat(pathModule.toNamespacedPath(path), req);
@ -1132,10 +1099,7 @@ fs.stat = function(path, callback) {
if (handleError((path = getPathFromURL(path)), callback))
return;
if (!nullCheck(path, callback)) return;
if (typeof path !== 'string' && !isUint8Array(path)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
['string', 'Buffer', 'URL']);
}
validatePath(path);
const req = new FSReqWrap();
req.oncomplete = callback;
binding.stat(pathModule.toNamespacedPath(path), req);
@ -1150,10 +1114,7 @@ fs.fstatSync = function(fd) {
fs.lstatSync = function(path) {
handleError((path = getPathFromURL(path)));
nullCheck(path);
if (typeof path !== 'string' && !isUint8Array(path)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
['string', 'Buffer', 'URL']);
}
validatePath(path);
binding.lstat(pathModule.toNamespacedPath(path));
return statsFromValues();
};
@ -1161,10 +1122,7 @@ fs.lstatSync = function(path) {
fs.statSync = function(path) {
handleError((path = getPathFromURL(path)));
nullCheck(path);
if (typeof path !== 'string' && !isUint8Array(path)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
['string', 'Buffer', 'URL']);
}
validatePath(path);
binding.stat(pathModule.toNamespacedPath(path));
return statsFromValues();
};
@ -1175,10 +1133,7 @@ fs.readlink = function(path, options, callback) {
if (handleError((path = getPathFromURL(path)), callback))
return;
if (!nullCheck(path, callback)) return;
if (typeof path !== 'string' && !isUint8Array(path)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'oldPath',
['string', 'Buffer', 'URL']);
}
validatePath(path, 'oldPath');
const req = new FSReqWrap();
req.oncomplete = callback;
binding.readlink(pathModule.toNamespacedPath(path), options.encoding, req);
@ -1188,10 +1143,7 @@ fs.readlinkSync = function(path, options) {
options = getOptions(options, {});
handleError((path = getPathFromURL(path)));
nullCheck(path);
if (typeof path !== 'string' && !isUint8Array(path)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'oldPath',
['string', 'Buffer', 'URL']);
}
validatePath(path, 'oldPath');
return binding.readlink(pathModule.toNamespacedPath(path), options.encoding);
};
@ -1243,15 +1195,8 @@ fs.symlink = function(target, path, type_, callback_) {
if (!nullCheck(target, callback)) return;
if (!nullCheck(path, callback)) return;
if (typeof target !== 'string' && !isUint8Array(target)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'target',
['string', 'Buffer', 'URL']);
}
if (typeof path !== 'string' && !isUint8Array(path)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
['string', 'Buffer', 'URL']);
}
validatePath(target, 'target');
validatePath(path);
const flags = stringToSymlinkType(type);
const req = new FSReqWrap();
@ -1267,14 +1212,8 @@ fs.symlinkSync = function(target, path, type) {
nullCheck(target);
nullCheck(path);
if (typeof target !== 'string' && !isUint8Array(target)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'target',
['string', 'Buffer', 'URL']);
}
if (typeof path !== 'string' && !isUint8Array(path)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
['string', 'Buffer', 'URL']);
}
validatePath(target, 'target');
validatePath(path);
const flags = stringToSymlinkType(type);
return binding.symlink(preprocessSymlinkDestination(target, type, path),
pathModule.toNamespacedPath(path), flags);
@ -1292,14 +1231,8 @@ fs.link = function(existingPath, newPath, callback) {
if (!nullCheck(existingPath, callback)) return;
if (!nullCheck(newPath, callback)) return;
if (typeof existingPath !== 'string' && !isUint8Array(existingPath)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'existingPath',
['string', 'Buffer', 'URL']);
}
if (typeof newPath !== 'string' && !isUint8Array(newPath)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'newPath',
['string', 'Buffer', 'URL']);
}
validatePath(existingPath, 'existingPath');
validatePath(newPath, 'newPath');
const req = new FSReqWrap();
req.oncomplete = callback;
@ -1314,14 +1247,8 @@ fs.linkSync = function(existingPath, newPath) {
handleError((newPath = getPathFromURL(newPath)));
nullCheck(existingPath);
nullCheck(newPath);
if (typeof existingPath !== 'string' && !isUint8Array(existingPath)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'existingPath',
['string', 'Buffer', 'URL']);
}
if (typeof newPath !== 'string' && !isUint8Array(newPath)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'newPath',
['string', 'Buffer', 'URL']);
}
validatePath(existingPath, 'existingPath');
validatePath(newPath, 'newPath');
return binding.link(pathModule.toNamespacedPath(existingPath),
pathModule.toNamespacedPath(newPath));
};
@ -1331,10 +1258,7 @@ fs.unlink = function(path, callback) {
if (handleError((path = getPathFromURL(path)), callback))
return;
if (!nullCheck(path, callback)) return;
if (typeof path !== 'string' && !isUint8Array(path)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
['string', 'Buffer', 'URL']);
}
validatePath(path);
const req = new FSReqWrap();
req.oncomplete = callback;
binding.unlink(pathModule.toNamespacedPath(path), req);
@ -1343,10 +1267,7 @@ fs.unlink = function(path, callback) {
fs.unlinkSync = function(path) {
handleError((path = getPathFromURL(path)));
nullCheck(path);
if (typeof path !== 'string' && !isUint8Array(path)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
['string', 'Buffer', 'URL']);
}
validatePath(path);
return binding.unlink(pathModule.toNamespacedPath(path));
};
@ -1417,10 +1338,7 @@ fs.chmod = function(path, mode, callback) {
return;
if (!nullCheck(path, callback)) return;
if (typeof path !== 'string' && !isUint8Array(path)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
['string', 'Buffer', 'URL']);
}
validatePath(path);
mode = modeNum(mode);
if (!isUint32(mode))
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'mode', 'integer');
@ -1433,10 +1351,7 @@ fs.chmod = function(path, mode, callback) {
fs.chmodSync = function(path, mode) {
handleError((path = getPathFromURL(path)));
nullCheck(path);
if (typeof path !== 'string' && !isUint8Array(path)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
['string', 'Buffer', 'URL']);
}
validatePath(path);
mode = modeNum(mode);
if (!isUint32(mode))
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'mode', 'integer');
@ -1489,10 +1404,7 @@ fs.chown = function(path, uid, gid, callback) {
return;
if (!nullCheck(path, callback)) return;
if (typeof path !== 'string' && !isUint8Array(path)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
['string', 'Buffer', 'URL']);
}
validatePath(path);
if (!isUint32(uid))
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'uid', 'integer');
if (!isUint32(gid))
@ -1506,10 +1418,7 @@ fs.chown = function(path, uid, gid, callback) {
fs.chownSync = function(path, uid, gid) {
handleError((path = getPathFromURL(path)));
nullCheck(path);
if (typeof path !== 'string' && !isUint8Array(path)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
['string', 'Buffer', 'URL']);
}
validatePath(path);
if (!isUint32(uid))
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'uid', 'integer');
if (!isUint32(gid))
@ -1548,10 +1457,7 @@ fs.utimes = function(path, atime, mtime, callback) {
return;
if (!nullCheck(path, callback)) return;
if (typeof path !== 'string' && !isUint8Array(path)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
['string', 'Buffer', 'URL']);
}
validatePath(path);
const req = new FSReqWrap();
req.oncomplete = callback;
@ -1564,10 +1470,7 @@ fs.utimes = function(path, atime, mtime, callback) {
fs.utimesSync = function(path, atime, mtime) {
handleError((path = getPathFromURL(path)));
nullCheck(path);
if (typeof path !== 'string' && !isUint8Array(path)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
['string', 'Buffer', 'URL']);
}
validatePath(path);
binding.utimes(pathModule.toNamespacedPath(path),
toUnixTimestamp(atime),
toUnixTimestamp(mtime));
@ -2279,14 +2182,8 @@ fs.copyFile = function(src, dest, flags, callback) {
if (!nullCheck(dest, callback))
return;
if (typeof src !== 'string' && !isUint8Array(src)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'src',
['string', 'Buffer', 'URL']);
}
if (typeof dest !== 'string' && !isUint8Array(dest)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'dest',
['string', 'Buffer', 'URL']);
}
validatePath(src, 'src');
validatePath(dest, 'dest');
src = pathModule._makeLong(src);
dest = pathModule._makeLong(dest);
@ -2306,14 +2203,8 @@ fs.copyFileSync = function(src, dest, flags) {
handleError(dest);
nullCheck(dest);
if (typeof src !== 'string' && !isUint8Array(src)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'src',
['string', 'Buffer', 'URL']);
}
if (typeof dest !== 'string' && !isUint8Array(dest)) {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'dest',
['string', 'Buffer', 'URL']);
}
validatePath(src, 'src');
validatePath(dest, 'dest');
src = pathModule._makeLong(src);
dest = pathModule._makeLong(dest);