diff --git a/lib/path.js b/lib/path.js index 2d09eb595a2e2a..bbe5f0b5be0716 100644 --- a/lib/path.js +++ b/lib/path.js @@ -11,10 +11,10 @@ function assertPath(path) { // Resolves . and .. elements in a path with directory names function normalizeStringWin32(path, allowAboveRoot) { var res = ''; + var lastSegmentLength = 0; var lastSlash = -1; var dots = 0; var code; - var isAboveRoot = false; for (var i = 0; i <= path.length; ++i) { if (i < path.length) code = path.charCodeAt(i); @@ -26,7 +26,7 @@ function normalizeStringWin32(path, allowAboveRoot) { if (lastSlash === i - 1 || dots === 1) { // NOOP } else if (lastSlash !== i - 1 && dots === 2) { - if (res.length < 2 || !isAboveRoot || + if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46/*.*/ || res.charCodeAt(res.length - 2) !== 46/*.*/) { if (res.length > 2) { @@ -37,20 +37,22 @@ function normalizeStringWin32(path, allowAboveRoot) { break; } if (j !== start) { - if (j === -1) + if (j === -1) { res = ''; - else + lastSegmentLength = 0; + } else { res = res.slice(0, j); + lastSegmentLength = j; + } lastSlash = i; dots = 0; - isAboveRoot = false; continue; } } else if (res.length === 2 || res.length === 1) { res = ''; + lastSegmentLength = 0; lastSlash = i; dots = 0; - isAboveRoot = false; continue; } } @@ -59,14 +61,14 @@ function normalizeStringWin32(path, allowAboveRoot) { res += '\\..'; else res = '..'; - isAboveRoot = true; + lastSegmentLength = 2; } } else { if (res.length > 0) res += '\\' + path.slice(lastSlash + 1, i); else res = path.slice(lastSlash + 1, i); - isAboveRoot = false; + lastSegmentLength = i - lastSlash - 1; } lastSlash = i; dots = 0; @@ -82,10 +84,10 @@ function normalizeStringWin32(path, allowAboveRoot) { // Resolves . and .. elements in a path with directory names function normalizeStringPosix(path, allowAboveRoot) { var res = ''; + var lastSegmentLength = 0; var lastSlash = -1; var dots = 0; var code; - var isAboveRoot = false; for (var i = 0; i <= path.length; ++i) { if (i < path.length) code = path.charCodeAt(i); @@ -97,7 +99,7 @@ function normalizeStringPosix(path, allowAboveRoot) { if (lastSlash === i - 1 || dots === 1) { // NOOP } else if (lastSlash !== i - 1 && dots === 2) { - if (res.length < 2 || !isAboveRoot || + if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46/*.*/ || res.charCodeAt(res.length - 2) !== 46/*.*/) { if (res.length > 2) { @@ -108,20 +110,22 @@ function normalizeStringPosix(path, allowAboveRoot) { break; } if (j !== start) { - if (j === -1) + if (j === -1) { res = ''; - else + lastSegmentLength = 0; + } else { res = res.slice(0, j); + lastSegmentLength = j; + } lastSlash = i; dots = 0; - isAboveRoot = false; continue; } } else if (res.length === 2 || res.length === 1) { res = ''; + lastSegmentLength = 0; lastSlash = i; dots = 0; - isAboveRoot = false; continue; } } @@ -130,14 +134,14 @@ function normalizeStringPosix(path, allowAboveRoot) { res += '/..'; else res = '..'; - isAboveRoot = true; + lastSegmentLength = 2; } } else { if (res.length > 0) res += '/' + path.slice(lastSlash + 1, i); else res = path.slice(lastSlash + 1, i); - isAboveRoot = false; + lastSegmentLength = i - lastSlash - 1; } lastSlash = i; dots = 0; diff --git a/test/parallel/test-path-normalize.js b/test/parallel/test-path-normalize.js index db91432b3e0955..0820052446367e 100644 --- a/test/parallel/test-path-normalize.js +++ b/test/parallel/test-path-normalize.js @@ -23,6 +23,10 @@ assert.strictEqual(path.win32.normalize('bar\\foo..\\..'), 'bar'); assert.strictEqual(path.win32.normalize('bar\\foo..\\..\\baz'), 'bar\\baz'); assert.strictEqual(path.win32.normalize('bar\\foo..\\'), 'bar\\foo..\\'); assert.strictEqual(path.win32.normalize('bar\\foo..'), 'bar\\foo..'); +assert.strictEqual(path.win32.normalize('..\\foo..\\..\\..\\bar'), + '..\\..\\bar'); +assert.strictEqual(path.win32.normalize('..\\...\\..\\.\\...\\..\\..\\bar'), + '..\\..\\bar'); assert.strictEqual(path.posix.normalize('./fixtures///b/../b/c.js'), 'fixtures/b/c.js'); @@ -37,3 +41,6 @@ assert.strictEqual(path.posix.normalize('bar/foo../..'), 'bar'); assert.strictEqual(path.posix.normalize('bar/foo../../baz'), 'bar/baz'); assert.strictEqual(path.posix.normalize('bar/foo../'), 'bar/foo../'); assert.strictEqual(path.posix.normalize('bar/foo..'), 'bar/foo..'); +assert.strictEqual(path.posix.normalize('../foo../../../bar'), '../../bar'); +assert.strictEqual(path.posix.normalize('../.../.././.../../../bar'), + '../../bar');