summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJames M Snell <jasnell@gmail.com>2017-12-13 14:24:34 -0800
committerJames M Snell <jasnell@gmail.com>2017-12-22 12:49:10 -0800
commit6100e12667429acad1827b6d918e512e55a7a6a7 (patch)
tree4fac815add3abf5d54112723798ecc78cb3e06fa /lib
parent92fc14a4595d460394cad8ad5a091dcc450068a5 (diff)
downloadandroid-node-v8-6100e12667429acad1827b6d918e512e55a7a6a7.tar.gz
android-node-v8-6100e12667429acad1827b6d918e512e55a7a6a7.tar.bz2
android-node-v8-6100e12667429acad1827b6d918e512e55a7a6a7.zip
fs: move type checking to js
PR-URL: https://github.com/nodejs/node/pull/17667 Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/fs.js463
-rw-r--r--lib/internal/errors.js2
2 files changed, 321 insertions, 144 deletions
diff --git a/lib/fs.js b/lib/fs.js
index 9554620a04..fe657c3c24 100644
--- a/lib/fs.js
+++ b/lib/fs.js
@@ -63,6 +63,9 @@ const errnoException = util._errnoException;
let truncateWarn = true;
+function isInt32(n) { return n === (n | 0); }
+function isUint32(n) { return n === (n >>> 0); }
+
function showTruncateDeprecation() {
if (truncateWarn) {
process.emitWarning(
@@ -636,10 +639,8 @@ fs.readFileSync = function(path, options) {
};
fs.close = function(fd, callback) {
- 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 (!isUint32(fd))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'fd', 'integer');
const req = new FSReqWrap();
req.oncomplete = makeCallback(callback);
@@ -647,10 +648,8 @@ fs.close = function(fd, callback) {
};
fs.closeSync = function(fd) {
- 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 (!isUint32(fd))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'fd', 'integer');
return binding.close(fd);
};
@@ -673,7 +672,15 @@ fs.open = function(path, flags, mode, callback_) {
return;
if (!nullCheck(path, callback)) return;
- var req = new FSReqWrap();
+ if (typeof path !== 'string' && !isUint8Array(path)) {
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
+ ['string', 'Buffer', 'URL']);
+ }
+
+ if (!isUint32(mode))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'mode', 'integer');
+
+ const req = new FSReqWrap();
req.oncomplete = callback;
binding.open(pathModule.toNamespacedPath(path),
@@ -686,15 +693,21 @@ 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']);
+ }
+
+ if (!isUint32(mode))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'mode', 'integer');
+
return binding.open(pathModule.toNamespacedPath(path),
stringToFlags(flags), mode);
};
fs.read = function(fd, buffer, offset, length, position, callback) {
- 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 (!isUint32(fd))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'fd', 'integer');
if (!isUint8Array(buffer))
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'buffer',
['Buffer', 'Uint8Array']);
@@ -714,7 +727,7 @@ fs.read = function(fd, buffer, offset, length, position, callback) {
if (length < 0 || offset + length > buffer.length)
throw new errors.RangeError('ERR_OUT_OF_RANGE', 'length');
- if (!Number.isInteger(position))
+ if (!isUint32(position))
position = -1;
function wrapper(err, bytesRead) {
@@ -732,10 +745,8 @@ Object.defineProperty(fs.read, internalUtil.customPromisifyArgs,
{ value: ['bytesRead', 'buffer'], enumerable: false });
fs.readSync = function(fd, buffer, offset, length, position) {
- 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 (!isUint32(fd))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'fd', 'integer');
if (!isUint8Array(buffer))
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'buffer',
['Buffer', 'Uint8Array']);
@@ -753,7 +764,7 @@ fs.readSync = function(fd, buffer, offset, length, position) {
if (length < 0 || offset + length > buffer.length)
throw new errors.RangeError('ERR_OUT_OF_RANGE', 'length');
- if (!Number.isInteger(position))
+ if (!isUint32(position))
position = -1;
return binding.read(fd, buffer, offset, length, position);
@@ -769,20 +780,25 @@ fs.write = function(fd, buffer, offset, length, position, callback) {
callback(err, written || 0, buffer);
}
- var req = new FSReqWrap();
+ if (!isUint32(fd))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'fd', 'integer');
+
+ const req = new FSReqWrap();
req.oncomplete = wrapper;
if (isUint8Array(buffer)) {
callback = maybeCallback(callback || position || length || offset);
- if (typeof offset !== 'number') {
+ if (typeof offset !== 'number')
offset = 0;
- }
- if (typeof length !== 'number') {
+ if (typeof length !== 'number')
length = buffer.length - offset;
- }
- if (typeof position !== 'number') {
+ if (typeof position !== 'number')
position = null;
- }
+ const byteLength = buffer.byteLength;
+ if (offset > byteLength)
+ throw new errors.RangeError('ERR_OUT_OF_RANGE', 'offset');
+ if (offset + length > byteLength || offset + length > kMaxLength)
+ throw new errors.RangeError('ERR_OUT_OF_RANGE', 'length');
return binding.writeBuffer(fd, buffer, offset, length, position, req);
}
@@ -809,6 +825,8 @@ Object.defineProperty(fs.write, internalUtil.customPromisifyArgs,
// OR
// fs.writeSync(fd, string[, position[, encoding]]);
fs.writeSync = function(fd, buffer, offset, length, position) {
+ if (!isUint32(fd))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'fd', 'integer');
if (isUint8Array(buffer)) {
if (position === undefined)
position = null;
@@ -816,6 +834,11 @@ fs.writeSync = function(fd, buffer, offset, length, position) {
offset = 0;
if (typeof length !== 'number')
length = buffer.length - offset;
+ const byteLength = buffer.byteLength;
+ if (offset > byteLength)
+ throw new errors.RangeError('ERR_OUT_OF_RANGE', 'offset');
+ if (offset + length > byteLength || offset + length > kMaxLength)
+ throw new errors.RangeError('ERR_OUT_OF_RANGE', 'length');
return binding.writeBuffer(fd, buffer, offset, length, position);
}
if (typeof buffer !== 'string')
@@ -835,7 +858,16 @@ fs.rename = function(oldPath, newPath, callback) {
if (!nullCheck(oldPath, callback)) return;
if (!nullCheck(newPath, callback)) return;
- var req = new FSReqWrap();
+
+ 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']);
+ }
+ const req = new FSReqWrap();
req.oncomplete = callback;
binding.rename(pathModule.toNamespacedPath(oldPath),
pathModule.toNamespacedPath(newPath),
@@ -847,6 +879,14 @@ 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']);
+ }
return binding.rename(pathModule.toNamespacedPath(oldPath),
pathModule.toNamespacedPath(newPath));
};
@@ -897,35 +937,26 @@ fs.truncateSync = function(path, len) {
return ret;
};
-fs.ftruncate = function(fd, len, callback) {
+fs.ftruncate = function(fd, len = 0, callback) {
if (typeof len === 'function') {
callback = len;
len = 0;
- } else if (len === undefined) {
- len = 0;
}
- 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(len))
- throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'len', 'number');
+ if (!isUint32(fd))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'fd', 'integer');
+ if (!isInt32(len))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'len', 'integer');
len = Math.max(0, len);
const req = new FSReqWrap();
req.oncomplete = makeCallback(callback);
binding.ftruncate(fd, len, req);
};
-fs.ftruncateSync = function(fd, len) {
- if (len === undefined) {
- len = 0;
- }
- 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(len))
- throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'len', 'number');
+fs.ftruncateSync = function(fd, len = 0) {
+ if (!isUint32(fd))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'fd', 'integer');
+ if (!isInt32(len))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'len', 'integer');
len = Math.max(0, len);
return binding.ftruncate(fd, len);
};
@@ -935,7 +966,11 @@ fs.rmdir = function(path, callback) {
if (handleError((path = getPathFromURL(path)), callback))
return;
if (!nullCheck(path, callback)) return;
- var req = new FSReqWrap();
+ if (typeof path !== 'string' && !isUint8Array(path)) {
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
+ ['string', 'Buffer', 'URL']);
+ }
+ const req = new FSReqWrap();
req.oncomplete = callback;
binding.rmdir(pathModule.toNamespacedPath(path), req);
};
@@ -943,42 +978,38 @@ 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']);
+ }
return binding.rmdir(pathModule.toNamespacedPath(path));
};
fs.fdatasync = function(fd, callback) {
- 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 (!isUint32(fd))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'fd', 'integer');
const req = new FSReqWrap();
req.oncomplete = makeCallback(callback);
binding.fdatasync(fd, req);
};
fs.fdatasyncSync = function(fd) {
- 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 (!isUint32(fd))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'fd', 'integer');
return binding.fdatasync(fd);
};
fs.fsync = function(fd, callback) {
- 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 (!isUint32(fd))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'fd', 'integer');
const req = new FSReqWrap();
req.oncomplete = makeCallback(callback);
binding.fsync(fd, req);
};
fs.fsyncSync = function(fd) {
- 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 (!isUint32(fd))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'fd', 'integer');
return binding.fsync(fd);
};
@@ -988,18 +1019,31 @@ fs.mkdir = function(path, mode, callback) {
if (handleError((path = getPathFromURL(path)), callback))
return;
if (!nullCheck(path, callback)) return;
- var req = new FSReqWrap();
+
+ if (typeof path !== 'string' && !isUint8Array(path)) {
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
+ ['string', 'Buffer', 'URL']);
+ }
+ mode = modeNum(mode, 0o777);
+ if (!isUint32(mode))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'mode', 'integer');
+
+ const req = new FSReqWrap();
req.oncomplete = callback;
- binding.mkdir(pathModule.toNamespacedPath(path),
- modeNum(mode, 0o777),
- req);
+ binding.mkdir(pathModule.toNamespacedPath(path), mode, req);
};
fs.mkdirSync = function(path, mode) {
handleError((path = getPathFromURL(path)));
nullCheck(path);
- return binding.mkdir(pathModule.toNamespacedPath(path),
- modeNum(mode, 0o777));
+ if (typeof path !== 'string' && !isUint8Array(path)) {
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
+ ['string', 'Buffer', 'URL']);
+ }
+ mode = modeNum(mode, 0o777);
+ if (!isUint32(mode))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'mode', 'integer');
+ return binding.mkdir(pathModule.toNamespacedPath(path), mode);
};
fs.readdir = function(path, options, callback) {
@@ -1008,7 +1052,13 @@ fs.readdir = function(path, options, callback) {
if (handleError((path = getPathFromURL(path)), callback))
return;
if (!nullCheck(path, callback)) return;
- var req = new FSReqWrap();
+
+ if (typeof path !== 'string' && !isUint8Array(path)) {
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
+ ['string', 'Buffer', 'URL']);
+ }
+
+ const req = new FSReqWrap();
req.oncomplete = callback;
binding.readdir(pathModule.toNamespacedPath(path), options.encoding, req);
};
@@ -1017,14 +1067,16 @@ 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']);
+ }
return binding.readdir(pathModule.toNamespacedPath(path), options.encoding);
};
fs.fstat = function(fd, callback) {
- 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 (!isUint32(fd))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'fd', 'integer');
const req = new FSReqWrap();
req.oncomplete = makeStatsCallback(callback);
binding.fstat(fd, req);
@@ -1035,7 +1087,11 @@ fs.lstat = function(path, callback) {
if (handleError((path = getPathFromURL(path)), callback))
return;
if (!nullCheck(path, callback)) return;
- var req = new FSReqWrap();
+ if (typeof path !== 'string' && !isUint8Array(path)) {
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
+ ['string', 'Buffer', 'URL']);
+ }
+ const req = new FSReqWrap();
req.oncomplete = callback;
binding.lstat(pathModule.toNamespacedPath(path), req);
};
@@ -1045,16 +1101,18 @@ fs.stat = function(path, callback) {
if (handleError((path = getPathFromURL(path)), callback))
return;
if (!nullCheck(path, callback)) return;
- var req = new FSReqWrap();
+ if (typeof path !== 'string' && !isUint8Array(path)) {
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
+ ['string', 'Buffer', 'URL']);
+ }
+ const req = new FSReqWrap();
req.oncomplete = callback;
binding.stat(pathModule.toNamespacedPath(path), req);
};
fs.fstatSync = function(fd) {
- 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 (!isUint32(fd))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'fd', 'integer');
binding.fstat(fd);
return statsFromValues();
};
@@ -1062,6 +1120,10 @@ 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']);
+ }
binding.lstat(pathModule.toNamespacedPath(path));
return statsFromValues();
};
@@ -1069,6 +1131,10 @@ 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']);
+ }
binding.stat(pathModule.toNamespacedPath(path));
return statsFromValues();
};
@@ -1079,7 +1145,11 @@ fs.readlink = function(path, options, callback) {
if (handleError((path = getPathFromURL(path)), callback))
return;
if (!nullCheck(path, callback)) return;
- var req = new FSReqWrap();
+ if (typeof path !== 'string' && !isUint8Array(path)) {
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'oldPath',
+ ['string', 'Buffer', 'URL']);
+ }
+ const req = new FSReqWrap();
req.oncomplete = callback;
binding.readlink(pathModule.toNamespacedPath(path), options.encoding, req);
};
@@ -1088,6 +1158,10 @@ 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']);
+ }
return binding.readlink(pathModule.toNamespacedPath(path), options.encoding);
};
@@ -1106,6 +1180,27 @@ function preprocessSymlinkDestination(path, type, linkPath) {
}
}
+function stringToSymlinkType(type) {
+ let flags = 0;
+ if (typeof type === 'string') {
+ switch (type) {
+ case 'dir':
+ flags |= constants.UV_FS_SYMLINK_DIR;
+ break;
+ case 'junction':
+ flags |= constants.UV_FS_SYMLINK_JUNCTION;
+ break;
+ case 'file':
+ break;
+ default:
+ const err = new errors.Error('ERR_FS_INVALID_SYMLINK_TYPE', type);
+ Error.captureStackTrace(err, stringToSymlinkType);
+ throw err;
+ }
+ }
+ return flags;
+}
+
fs.symlink = function(target, path, type_, callback_) {
var type = (typeof type_ === 'string' ? type_ : null);
var callback = makeCallback(arguments[arguments.length - 1]);
@@ -1119,13 +1214,20 @@ fs.symlink = function(target, path, type_, callback_) {
if (!nullCheck(target, callback)) return;
if (!nullCheck(path, callback)) return;
- var req = new FSReqWrap();
- req.oncomplete = callback;
+ 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']);
+ }
+ const flags = stringToSymlinkType(type);
+ const req = new FSReqWrap();
+ req.oncomplete = callback;
binding.symlink(preprocessSymlinkDestination(target, type, path),
- pathModule.toNamespacedPath(path),
- type,
- req);
+ pathModule.toNamespacedPath(path), flags, req);
};
fs.symlinkSync = function(target, path, type) {
@@ -1135,9 +1237,17 @@ 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']);
+ }
+ const flags = stringToSymlinkType(type);
return binding.symlink(preprocessSymlinkDestination(target, type, path),
- pathModule.toNamespacedPath(path),
- type);
+ pathModule.toNamespacedPath(path), flags);
};
fs.link = function(existingPath, newPath, callback) {
@@ -1152,7 +1262,16 @@ fs.link = function(existingPath, newPath, callback) {
if (!nullCheck(existingPath, callback)) return;
if (!nullCheck(newPath, callback)) return;
- var req = new FSReqWrap();
+ 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']);
+ }
+
+ const req = new FSReqWrap();
req.oncomplete = callback;
binding.link(pathModule.toNamespacedPath(existingPath),
@@ -1165,6 +1284,14 @@ 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']);
+ }
return binding.link(pathModule.toNamespacedPath(existingPath),
pathModule.toNamespacedPath(newPath));
};
@@ -1174,7 +1301,11 @@ fs.unlink = function(path, callback) {
if (handleError((path = getPathFromURL(path)), callback))
return;
if (!nullCheck(path, callback)) return;
- var req = new FSReqWrap();
+ if (typeof path !== 'string' && !isUint8Array(path)) {
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
+ ['string', 'Buffer', 'URL']);
+ }
+ const req = new FSReqWrap();
req.oncomplete = callback;
binding.unlink(pathModule.toNamespacedPath(path), req);
};
@@ -1182,17 +1313,19 @@ 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']);
+ }
return binding.unlink(pathModule.toNamespacedPath(path));
};
fs.fchmod = function(fd, mode, callback) {
mode = modeNum(mode);
- 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(mode))
- throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'mode', 'number');
+ if (!isUint32(fd))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'fd', 'integer');
+ if (!isUint32(mode))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'mode', 'integer');
if (mode < 0 || mode > 0o777)
throw new errors.RangeError('ERR_OUT_OF_RANGE', 'mode');
@@ -1203,12 +1336,10 @@ fs.fchmod = function(fd, mode, callback) {
fs.fchmodSync = function(fd, mode) {
mode = modeNum(mode);
- 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(mode))
- throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'mode', 'number');
+ if (!isUint32(fd))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'fd', 'integer');
+ if (!isUint32(mode))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'mode', 'integer');
if (mode < 0 || mode > 0o777)
throw new errors.RangeError('ERR_OUT_OF_RANGE', 'mode');
return binding.fchmod(fd, mode);
@@ -1257,17 +1388,31 @@ fs.chmod = function(path, mode, callback) {
if (handleError((path = getPathFromURL(path)), callback))
return;
if (!nullCheck(path, callback)) return;
- var req = new FSReqWrap();
+
+ if (typeof path !== 'string' && !isUint8Array(path)) {
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
+ ['string', 'Buffer', 'URL']);
+ }
+ mode = modeNum(mode);
+ if (!isUint32(mode))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'mode', 'integer');
+
+ const req = new FSReqWrap();
req.oncomplete = callback;
- binding.chmod(pathModule.toNamespacedPath(path),
- modeNum(mode),
- req);
+ binding.chmod(pathModule.toNamespacedPath(path), mode, req);
};
fs.chmodSync = function(path, mode) {
handleError((path = getPathFromURL(path)));
nullCheck(path);
- return binding.chmod(pathModule.toNamespacedPath(path), modeNum(mode));
+ if (typeof path !== 'string' && !isUint8Array(path)) {
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
+ ['string', 'Buffer', 'URL']);
+ }
+ mode = modeNum(mode);
+ if (!isUint32(mode))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'mode', 'integer');
+ return binding.chmod(pathModule.toNamespacedPath(path), mode);
};
if (constants.O_SYMLINK !== undefined) {
@@ -1289,18 +1434,12 @@ if (constants.O_SYMLINK !== undefined) {
}
fs.fchown = function(fd, uid, gid, callback) {
- 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');
+ if (!isUint32(fd))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'fd', 'integer');
+ 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');
const req = new FSReqWrap();
req.oncomplete = makeCallback(callback);
@@ -1308,18 +1447,12 @@ fs.fchown = function(fd, uid, gid, callback) {
};
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');
+ if (!isUint32(fd))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'fd', 'integer');
+ 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');
return binding.fchown(fd, uid, gid);
};
@@ -1329,7 +1462,17 @@ fs.chown = function(path, uid, gid, callback) {
if (handleError((path = getPathFromURL(path)), callback))
return;
if (!nullCheck(path, callback)) return;
- var req = new FSReqWrap();
+
+ if (typeof path !== 'string' && !isUint8Array(path)) {
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
+ ['string', 'Buffer', 'URL']);
+ }
+ 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');
+
+ const req = new FSReqWrap();
req.oncomplete = callback;
binding.chown(pathModule.toNamespacedPath(path), uid, gid, req);
};
@@ -1337,6 +1480,14 @@ 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']);
+ }
+ 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');
return binding.chown(pathModule.toNamespacedPath(path), uid, gid);
};
@@ -1370,7 +1521,13 @@ fs.utimes = function(path, atime, mtime, callback) {
if (handleError((path = getPathFromURL(path)), callback))
return;
if (!nullCheck(path, callback)) return;
- var req = new FSReqWrap();
+
+ if (typeof path !== 'string' && !isUint8Array(path)) {
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
+ ['string', 'Buffer', 'URL']);
+ }
+
+ const req = new FSReqWrap();
req.oncomplete = callback;
binding.utimes(pathModule.toNamespacedPath(path),
toUnixTimestamp(atime),
@@ -1381,16 +1538,18 @@ fs.utimes = function(path, atime, mtime, callback) {
fs.utimesSync = function(path, atime, mtime) {
handleError((path = getPathFromURL(path)));
nullCheck(path);
- atime = toUnixTimestamp(atime);
- mtime = toUnixTimestamp(mtime);
- binding.utimes(pathModule.toNamespacedPath(path), atime, mtime);
+ if (typeof path !== 'string' && !isUint8Array(path)) {
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'path',
+ ['string', 'Buffer', 'URL']);
+ }
+ binding.utimes(pathModule.toNamespacedPath(path),
+ toUnixTimestamp(atime),
+ toUnixTimestamp(mtime));
};
fs.futimes = function(fd, atime, mtime, callback) {
- 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 (!isUint32(fd))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'fd', 'integer');
atime = toUnixTimestamp(atime, 'atime');
mtime = toUnixTimestamp(mtime, 'mtime');
const req = new FSReqWrap();
@@ -1399,10 +1558,8 @@ fs.futimes = function(fd, atime, mtime, callback) {
};
fs.futimesSync = function(fd, atime, mtime) {
- 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 (!isUint32(fd))
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'fd', 'integer');
atime = toUnixTimestamp(atime, 'atime');
mtime = toUnixTimestamp(mtime, 'mtime');
binding.futimes(fd, atime, mtime);
@@ -2098,6 +2255,15 @@ 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']);
+ }
+
src = pathModule._makeLong(src);
dest = pathModule._makeLong(dest);
flags = flags | 0;
@@ -2116,6 +2282,15 @@ 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']);
+ }
+
src = pathModule._makeLong(src);
dest = pathModule._makeLong(dest);
flags = flags | 0;
diff --git a/lib/internal/errors.js b/lib/internal/errors.js
index 5b18a7026e..779343e066 100644
--- a/lib/internal/errors.js
+++ b/lib/internal/errors.js
@@ -307,6 +307,8 @@ E('ERR_ENCODING_INVALID_ENCODED_DATA',
'The encoded data was not valid for encoding %s');
E('ERR_ENCODING_NOT_SUPPORTED', 'The "%s" encoding is not supported');
E('ERR_FALSY_VALUE_REJECTION', 'Promise was rejected with falsy value');
+E('ERR_FS_INVALID_SYMLINK_TYPE',
+ 'Symlink type must be one of "dir", "file", or "junction". Received "%s"');
E('ERR_HTTP2_ALREADY_SHUTDOWN',
'Http2Session is already shutdown or destroyed');
E('ERR_HTTP2_CONNECT_AUTHORITY',