-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
path: add type checking for path inputs #1153
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,14 @@ | ||
'use strict'; | ||
|
||
const util = require('util'); | ||
const isWindows = process.platform === 'win32'; | ||
|
||
function assertPath(path) { | ||
if (typeof path !== 'string') | ||
throw new TypeError('Path must be a string. Received ' + | ||
util.inspect(path)); | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe something like this makes it more clear which argument is of wrong type: function assertPaths() {
[].slice.call(arguments).forEach(function (path, i) {
if (typeof path !== 'string')
throw new TypeError(util.format('Argument %d must be a string.' +
' Received %s', i + 1, util.inspect(path));
});
} assertPaths(from, to); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The forEach isn't particularly speedy either. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. True, probably better to keep it the way it is then. I wish rest parameters were in V8 already 😭 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The fastest way to write it is not that much harder actually ;p function assertPaths() {
for (var i = 0; i < arguments.length; ++i) {
if (typeof arguments[i] !== 'string')
throw new TypeError(util.format('Argument %d must be a string.' +
' Received %s', i + 1, util.inspect(arguments[i])));
}
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, that didn't occur to me of course, because I secretly hate classic There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd rather not have this be over-engineered, we're just checking for argument types - anyways, as is, you could see which argument is bad via the stack trace. |
||
// resolves . and .. elements in a path array with directory names there | ||
// must be no slashes or device names (c:\) in the array | ||
// (so also no leading and trailing slashes - it does not distinguish | ||
|
@@ -84,10 +91,10 @@ win32.resolve = function() { | |
} | ||
} | ||
|
||
// Skip empty and invalid entries | ||
if (typeof path !== 'string') { | ||
throw new TypeError('Arguments to path.resolve must be strings'); | ||
} else if (!path) { | ||
assertPath(path); | ||
|
||
// Skip empty entries | ||
if (path === '') { | ||
continue; | ||
} | ||
|
||
|
@@ -137,6 +144,8 @@ win32.resolve = function() { | |
|
||
|
||
win32.normalize = function(path) { | ||
assertPath(path); | ||
|
||
var result = splitDeviceRe.exec(path), | ||
device = result[1] || '', | ||
isUnc = device && device.charAt(1) !== ':', | ||
|
@@ -165,6 +174,8 @@ win32.normalize = function(path) { | |
|
||
|
||
win32.isAbsolute = function(path) { | ||
assertPath(path); | ||
|
||
var result = splitDeviceRe.exec(path), | ||
device = result[1] || '', | ||
isUnc = !!device && device.charAt(1) !== ':'; | ||
|
@@ -210,6 +221,9 @@ win32.join = function() { | |
// to = 'C:\\orandea\\impl\\bbb' | ||
// The output of the function should be: '..\\..\\impl\\bbb' | ||
win32.relative = function(from, to) { | ||
assertPath(from); | ||
assertPath(to); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will be a little weird because the error will always be "path" no matter which is missing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe this should be changed to be like line #328? |
||
|
||
from = win32.resolve(from); | ||
to = win32.resolve(to); | ||
|
||
|
@@ -287,6 +301,8 @@ win32._makeLong = function(path) { | |
|
||
|
||
win32.dirname = function(path) { | ||
assertPath(path); | ||
|
||
var result = win32SplitPath(path), | ||
root = result[0], | ||
dir = result[1]; | ||
|
@@ -306,6 +322,11 @@ win32.dirname = function(path) { | |
|
||
|
||
win32.basename = function(path, ext) { | ||
assertPath(path); | ||
|
||
if (ext !== undefined && typeof ext !== 'string') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This causes breakage when used as an Array.map callback, which will pass in an index for Noticed because I had: result = directories.map(path.basename); And upgrading now throws:
Technically an improper use of |
||
throw new TypeError('ext must be a string'); | ||
|
||
var f = win32SplitPath(path)[2]; | ||
// TODO: make this comparison case-insensitive on windows? | ||
if (ext && f.substr(-1 * ext.length) === ext) { | ||
|
@@ -316,6 +337,7 @@ win32.basename = function(path, ext) { | |
|
||
|
||
win32.extname = function(path) { | ||
assertPath(path); | ||
return win32SplitPath(path)[3]; | ||
}; | ||
|
||
|
@@ -351,11 +373,8 @@ win32.format = function(pathObject) { | |
|
||
|
||
win32.parse = function(pathString) { | ||
if (typeof pathString !== 'string') { | ||
throw new TypeError( | ||
"Parameter 'pathString' must be a string, not " + typeof pathString | ||
); | ||
} | ||
assertPath(pathString); | ||
|
||
var allParts = win32SplitPath(pathString); | ||
if (!allParts || allParts.length !== 4) { | ||
throw new TypeError("Invalid path '" + pathString + "'"); | ||
|
@@ -395,10 +414,10 @@ posix.resolve = function() { | |
for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { | ||
var path = (i >= 0) ? arguments[i] : process.cwd(); | ||
|
||
// Skip empty and invalid entries | ||
if (typeof path !== 'string') { | ||
throw new TypeError('Arguments to path.resolve must be strings'); | ||
} else if (!path) { | ||
assertPath(path); | ||
|
||
// Skip empty entries | ||
if (path === '') { | ||
continue; | ||
} | ||
|
||
|
@@ -419,6 +438,8 @@ posix.resolve = function() { | |
// path.normalize(path) | ||
// posix version | ||
posix.normalize = function(path) { | ||
assertPath(path); | ||
|
||
var isAbsolute = posix.isAbsolute(path), | ||
trailingSlash = path.substr(-1) === '/'; | ||
|
||
|
@@ -437,6 +458,7 @@ posix.normalize = function(path) { | |
|
||
// posix version | ||
posix.isAbsolute = function(path) { | ||
assertPath(path); | ||
return path.charAt(0) === '/'; | ||
}; | ||
|
||
|
@@ -463,6 +485,9 @@ posix.join = function() { | |
// path.relative(from, to) | ||
// posix version | ||
posix.relative = function(from, to) { | ||
assertPath(from); | ||
assertPath(to); | ||
|
||
from = posix.resolve(from).substr(1); | ||
to = posix.resolve(to).substr(1); | ||
|
||
|
@@ -510,6 +535,8 @@ posix._makeLong = function(path) { | |
|
||
|
||
posix.dirname = function(path) { | ||
assertPath(path); | ||
|
||
var result = posixSplitPath(path), | ||
root = result[0], | ||
dir = result[1]; | ||
|
@@ -529,8 +556,13 @@ posix.dirname = function(path) { | |
|
||
|
||
posix.basename = function(path, ext) { | ||
assertPath(path); | ||
|
||
if (ext !== undefined && typeof ext !== 'string') | ||
throw new TypeError('ext must be a string'); | ||
|
||
var f = posixSplitPath(path)[2]; | ||
// TODO: make this comparison case-insensitive on windows? | ||
|
||
if (ext && f.substr(-1 * ext.length) === ext) { | ||
f = f.substr(0, f.length - ext.length); | ||
} | ||
|
@@ -539,6 +571,7 @@ posix.basename = function(path, ext) { | |
|
||
|
||
posix.extname = function(path) { | ||
assertPath(path); | ||
return posixSplitPath(path)[3]; | ||
}; | ||
|
||
|
@@ -566,11 +599,8 @@ posix.format = function(pathObject) { | |
|
||
|
||
posix.parse = function(pathString) { | ||
if (typeof pathString !== 'string') { | ||
throw new TypeError( | ||
"Parameter 'pathString' must be a string, not " + typeof pathString | ||
); | ||
} | ||
assertPath(pathString); | ||
|
||
var allParts = posixSplitPath(pathString); | ||
if (!allParts || allParts.length !== 4) { | ||
throw new TypeError("Invalid path '" + pathString + "'"); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor style nit: can you put braces around the body here? It doesn't fit on a single line.