diff --git a/lib/path.js b/lib/path.js index c7a5f0371761a8..1972bdc601aba6 100644 --- a/lib/path.js +++ b/lib/path.js @@ -26,33 +26,30 @@ var util = require('util'); // resolves . and .. elements in a path array with directory names there -// must be no slashes, empty elements, or device names (c:\) in the array +// must be no slashes or device names (c:\) in the array // (so also no leading and trailing slashes - it does not distinguish // relative and absolute paths) function normalizeArray(parts, allowAboveRoot) { - // if the path tries to go above the root, `up` ends up > 0 - var up = 0; - for (var i = parts.length - 1; i >= 0; i--) { - var last = parts[i]; - if (last === '.') { - parts.splice(i, 1); - } else if (last === '..') { - parts.splice(i, 1); - up++; - } else if (up) { - parts.splice(i, 1); - up--; - } - } + var res = []; + for (var i = 0; i < parts.length; i++) { + var p = parts[i]; + + // ignore empty parts + if (!p || p === '.') + continue; - // if the path is allowed to go above the root, restore leading ..s - if (allowAboveRoot) { - for (; up--; up) { - parts.unshift('..'); + if (p === '..') { + if (res.length && res[res.length - 1] !== '..') { + res.pop(); + } else if (allowAboveRoot) { + res.push('..'); + } + } else { + res.push(p); } } - return parts; + return res; } // Regex to split a windows path into three parts: [*, device, slash, @@ -154,12 +151,7 @@ win32.resolve = function() { // fails) // Normalize the tail path - - function f(p) { - return !!p; - } - - resolvedTail = normalizeArray(resolvedTail.split(/[\\\/]+/).filter(f), + resolvedTail = normalizeArray(resolvedTail.split(/[\\\/]+/), !resolvedAbsolute).join('\\'); return (resolvedDevice + (resolvedAbsolute ? '\\' : '') + resolvedTail) || @@ -176,9 +168,7 @@ win32.normalize = function(path) { trailingSlash = /[\\\/]$/.test(tail); // Normalize the tail path - tail = normalizeArray(tail.split(/[\\\/]+/).filter(function(p) { - return !!p; - }), !isAbsolute).join('\\'); + tail = normalizeArray(tail.split(/[\\\/]+/), !isAbsolute).join('\\'); if (!tail && !isAbsolute) { tail = '.'; @@ -443,9 +433,8 @@ posix.resolve = function() { // handle relative paths to be safe (might happen when process.cwd() fails) // Normalize the path - resolvedPath = normalizeArray(resolvedPath.split('/').filter(function(p) { - return !!p; - }), !resolvedAbsolute).join('/'); + resolvedPath = normalizeArray(resolvedPath.split('/'), + !resolvedAbsolute).join('/'); return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; }; @@ -454,17 +443,10 @@ posix.resolve = function() { // posix version posix.normalize = function(path) { var isAbsolute = posix.isAbsolute(path), - trailingSlash = path.substr(-1) === '/', - segments = path.split('/'), - nonEmptySegments = []; + trailingSlash = path.substr(-1) === '/'; // Normalize the path - for (var i = 0; i < segments.length; i++) { - if (segments[i]) { - nonEmptySegments.push(segments[i]); - } - } - path = normalizeArray(nonEmptySegments, !isAbsolute).join('/'); + path = normalizeArray(path.split('/'), !isAbsolute).join('/'); if (!path && !isAbsolute) { path = '.';