From d1e13c2b3924123dae4087c84341bd93718314dd Mon Sep 17 00:00:00 2001 From: Owen Smith Date: Mon, 29 Feb 2016 10:39:19 -0500 Subject: [PATCH] path: fix path.relative() for prefixes at device root Fixes #5485 --- lib/path.js | 34 ++++++++++++++++++++++------------ test/parallel/test-path.js | 10 ++++++++-- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/lib/path.js b/lib/path.js index bc9667c7b88cc3..5a066907514f9b 100644 --- a/lib/path.js +++ b/lib/path.js @@ -618,7 +618,7 @@ const win32 = { // We get here if `from` is the exact base path for `to`. // For example: from='C:\\foo\\bar'; to='C:\\foo\\bar\\baz' return toOrig.slice(toStart + i + 1); - } else if (lastCommonSep === 2) { + } else if (i === 2) { // We get here if `from` is the device root. // For example: from='C:\\'; to='C:\\foo' return toOrig.slice(toStart + i); @@ -629,7 +629,7 @@ const win32 = { // We get here if `to` is the exact base path for `from`. // For example: from='C:\\foo\\bar'; to='C:\\foo' lastCommonSep = i; - } else if (lastCommonSep === 2) { + } else if (i === 2) { // We get here if `to` is the device root. // For example: from='C:\\foo\\bar'; to='C:\\' lastCommonSep = 3; @@ -1300,16 +1300,26 @@ const posix = { var i = 0; for (; i <= length; ++i) { if (i === length) { - if (lastCommonSep === -1) { - lastCommonSep = i; - } else if (toLen > length && to.charCodeAt(i + 1) === 47/*/*/) { - // We get here if `from` is the exact base path for `to`. - // For example: from='/foo/bar'; to='/foo/bar/baz' - return to.slice(i + 2); - } else if (fromLen > length && from.charCodeAt(i + 1) === 47/*/*/) { - // We get here if `to` is the exact base path for `from`. - // For example: from='/foo/bar/baz'; to='/foo/bar' - lastCommonSep = i; + if (toLen > length) { + if (to.charCodeAt(toStart + i) === 47/*/*/) { + // We get here if `from` is the exact base path for `to`. + // For example: from='/foo/bar'; to='/foo/bar/baz' + return to.slice(toStart + i + 1); + } else if (i === 0) { + // We get here if `from` is the root + // For example: from='/'; to='/foo' + return to.slice(toStart + i); + } + } else if (fromLen > length) { + if (from.charCodeAt(fromStart + i) === 47/*/*/) { + // We get here if `to` is the exact base path for `from`. + // For example: from='/foo/bar/baz'; to='/foo/bar' + lastCommonSep = i; + } else if (i === 0) { + // We get here if `to` is the root. + // For example: from='/foo'; to='/' + lastCommonSep = 0; + } } break; } diff --git a/test/parallel/test-path.js b/test/parallel/test-path.js index c7854bc8d9d08b..fce54a52fb3a9b 100644 --- a/test/parallel/test-path.js +++ b/test/parallel/test-path.js @@ -476,7 +476,11 @@ const relativeTests = [ ['\\\\foo\\bar', '\\\\foo\\bar\\baz', 'baz'], ['\\\\foo\\bar\\baz', '\\\\foo\\bar', '..'], ['\\\\foo\\bar\\baz-quux', '\\\\foo\\bar\\baz', '..\\baz'], - ['\\\\foo\\bar\\baz', '\\\\foo\\bar\\baz-quux', '..\\baz-quux'] + ['\\\\foo\\bar\\baz', '\\\\foo\\bar\\baz-quux', '..\\baz-quux'], + ['C:\\baz-quux', 'C:\\baz', '..\\baz'], + ['C:\\baz', 'C:\\baz-quux', '..\\baz-quux'], + ['\\\\foo\\baz-quux', '\\\\foo\\baz', '..\\baz'], + ['\\\\foo\\baz', '\\\\foo\\baz-quux', '..\\baz-quux'] ] ], [ path.posix.relative, @@ -490,7 +494,9 @@ const relativeTests = [ ['/foo/test', '/foo/test/bar/package.json', 'bar/package.json'], ['/Users/a/web/b/test/mails', '/Users/a/web/b', '../..'], ['/foo/bar/baz-quux', '/foo/bar/baz', '../baz'], - ['/foo/bar/baz', '/foo/bar/baz-quux', '../baz-quux'] + ['/foo/bar/baz', '/foo/bar/baz-quux', '../baz-quux'], + ['/baz-quux', '/baz', '../baz'], + ['/baz', '/baz-quux', '../baz-quux'] ] ] ];