Skip to content
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

Closed
wants to merge 1 commit into from
Closed

path: add type checking for path inputs #1153

wants to merge 1 commit into from

Conversation

cjihrig
Copy link
Contributor

@cjihrig cjihrig commented Mar 14, 2015

This commit adds type checking of path inputs to exported methods in the path module. The exception is _makeLong(), which seems to explicitly support any data type.

Closes #1139

This commit adds type checking of path inputs to exported methods
in the path module. The exception is _makeLong, which seems to
explicitly support any data type.
@@ -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);
Copy link
Contributor

Choose a reason for hiding this comment

The 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.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe this should be changed to be like line #328?

@Fishrock123
Copy link
Contributor

LGTM other than one comment.

throw new TypeError('Path must be a string. Received ' +
util.inspect(path));
}

Copy link
Contributor

Choose a reason for hiding this comment

The 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);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[].slice.call(arguments) <-- slow

The forEach isn't particularly speedy either.

Copy link
Contributor

Choose a reason for hiding this comment

The 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 😭

Copy link
Contributor

Choose a reason for hiding this comment

The 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])));
  }
}

Copy link
Contributor

Choose a reason for hiding this comment

The 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 for loops. I have to jsperf argument iteration sometimes.

Copy link
Contributor

Choose a reason for hiding this comment

The 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.

@brendanashworth
Copy link
Contributor

LGTM

@silverwind
Copy link
Contributor

Overall looking fine to me, I hope the perf hit isn't too big on this.

function assertPath(path) {
if (typeof path !== 'string')
throw new TypeError('Path must be a string. Received ' +
util.inspect(path));
Copy link
Member

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.

@bnoordhuis
Copy link
Member

LGTM at a quick glance.

cjihrig added a commit that referenced this pull request Mar 16, 2015
This commit adds type checking of path inputs to exported methods
in the path module. The exception is _makeLong(), which seems to
explicitly support any data type.

Fixes: #1139
PR-URL: #1153
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
Reviewed-By: Brendan Ashworth <brendan.ashworth@me.com>
@cjihrig
Copy link
Contributor Author

cjihrig commented Mar 16, 2015

Landed in eb995d6

@cjihrig cjihrig closed this Mar 16, 2015
@cjihrig cjihrig deleted the 1139 branch March 16, 2015 16:52
@rvagg rvagg mentioned this pull request Mar 17, 2015
@rvagg rvagg mentioned this pull request Mar 20, 2015
rvagg added a commit that referenced this pull request Mar 20, 2015
Notable Changes:

* path: New type-checking on path.resolve()
  <#1153> uncovered some edge-cases
  being relied upon in the wild, most notably path.dirname(undefined).
  Type-checking has been loosened for path.dirname(), path.basename(),
  and path.extname(), (Colin Ihrig)
  <#1216>.
* querystring: Internal optimizations in querystring.parse() and
  querystring.stringify() <#847>
  prevented Number literals from being properly converted via
  querystring.escape() <#1208>,
  exposing a blind-spot in the test suite. The bug and the tests have
  now been fixed (Jeremiah Senkpiel)
  <#1213>.
jugglinmike pushed a commit to jugglinmike/jshint that referenced this pull request Apr 12, 2015
@@ -306,6 +322,11 @@ win32.dirname = function(path) {


win32.basename = function(path, ext) {
assertPath(path);

if (ext !== undefined && typeof ext !== 'string')
Copy link

Choose a reason for hiding this comment

The 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 ext.

Noticed because I had:

result = directories.map(path.basename);

And upgrading now throws:

>> TypeError: ext must be a string
>>     at posix.basename (path.js:550:11)
>>     at Array.map (native)

Technically an improper use of basename but still a small reduction in utility.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants