lib/path.js routines normalizeArray() and resolve() have for loops that
count down from end of an array. The loop indexes are initialized using
"array.length" rather than "array.length-1". The initial array element
accessed is always beyond the end of array and the value is 'undefined'.
Strangely, code exists that acts to ignore undefined values so that the
typos are unnoticeable.
Existing tests emit no errors either before or after changing to "length-1".
Tests _do_ start failing at "length-2". (Actually it is node that starts
to fail at "length-2" - that's a valid enough test...)
1. Express desired path.join behavior in tests.
2. Update fs.realpath to reflect new path.join behavior
3. Update url.resolve() to use new path.join behavior.
Any path.join or path.normalize that starts with a / will not go "above" that after normalization. This is important because /../foo is almost *always* some sort of error, and doesn't match the corollary in sh: `cd $p; pwd`
At the worse, this can be a vector for exploits, since a static file server might do path.join(docroot, path.normalize("/"+req)) to get the file. If the normalized request path could be something like "/../../../etc/passwd" then bad things could happen.
Before there was this comment:
Can't strip trailing slashes since module.js incorrectly
thinks dirname('/a/b/') should yield '/a/b' instead of '/a'.
But now, such thinking is corrected.
Previously path.dirname('/tmp') incorrectly returned '.'.
Unfortunately module.js incorrectly thinks dirname('/a/b/') should
yield '/a/b', so I can't strip trailing slashes yet. Once module.js
is fixed, then the commented-out code should be activated and a test
written for it.