path: refactor normalizeArray()
The normalizeArray() function now avoids using the slow Array#splice() method to improve performance and now also filters out empty path parts. Code that pre-filtered empty parts has been removed. PR-URL: https://github.com/joyent/node/pull/8724 Reviewed-by: Trevor Norris <trev.norris@gmail.com>
This commit is contained in:
parent
9483bfe6e3
commit
50d7401244
66
lib/path.js
66
lib/path.js
@ -26,33 +26,30 @@ var util = require('util');
|
|||||||
|
|
||||||
|
|
||||||
// resolves . and .. elements in a path array with directory names there
|
// 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
|
// (so also no leading and trailing slashes - it does not distinguish
|
||||||
// relative and absolute paths)
|
// relative and absolute paths)
|
||||||
function normalizeArray(parts, allowAboveRoot) {
|
function normalizeArray(parts, allowAboveRoot) {
|
||||||
// if the path tries to go above the root, `up` ends up > 0
|
var res = [];
|
||||||
var up = 0;
|
for (var i = 0; i < parts.length; i++) {
|
||||||
for (var i = parts.length - 1; i >= 0; i--) {
|
var p = parts[i];
|
||||||
var last = parts[i];
|
|
||||||
if (last === '.') {
|
// ignore empty parts
|
||||||
parts.splice(i, 1);
|
if (!p || p === '.')
|
||||||
} else if (last === '..') {
|
continue;
|
||||||
parts.splice(i, 1);
|
|
||||||
up++;
|
if (p === '..') {
|
||||||
} else if (up) {
|
if (res.length && res[res.length - 1] !== '..') {
|
||||||
parts.splice(i, 1);
|
res.pop();
|
||||||
up--;
|
} else if (allowAboveRoot) {
|
||||||
|
res.push('..');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
res.push(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the path is allowed to go above the root, restore leading ..s
|
return res;
|
||||||
if (allowAboveRoot) {
|
|
||||||
for (; up--; up) {
|
|
||||||
parts.unshift('..');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return parts;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Regex to split a windows path into three parts: [*, device, slash,
|
// Regex to split a windows path into three parts: [*, device, slash,
|
||||||
@ -154,12 +151,7 @@ win32.resolve = function() {
|
|||||||
// fails)
|
// fails)
|
||||||
|
|
||||||
// Normalize the tail path
|
// Normalize the tail path
|
||||||
|
resolvedTail = normalizeArray(resolvedTail.split(/[\\\/]+/),
|
||||||
function f(p) {
|
|
||||||
return !!p;
|
|
||||||
}
|
|
||||||
|
|
||||||
resolvedTail = normalizeArray(resolvedTail.split(/[\\\/]+/).filter(f),
|
|
||||||
!resolvedAbsolute).join('\\');
|
!resolvedAbsolute).join('\\');
|
||||||
|
|
||||||
return (resolvedDevice + (resolvedAbsolute ? '\\' : '') + resolvedTail) ||
|
return (resolvedDevice + (resolvedAbsolute ? '\\' : '') + resolvedTail) ||
|
||||||
@ -176,9 +168,7 @@ win32.normalize = function(path) {
|
|||||||
trailingSlash = /[\\\/]$/.test(tail);
|
trailingSlash = /[\\\/]$/.test(tail);
|
||||||
|
|
||||||
// Normalize the tail path
|
// Normalize the tail path
|
||||||
tail = normalizeArray(tail.split(/[\\\/]+/).filter(function(p) {
|
tail = normalizeArray(tail.split(/[\\\/]+/), !isAbsolute).join('\\');
|
||||||
return !!p;
|
|
||||||
}), !isAbsolute).join('\\');
|
|
||||||
|
|
||||||
if (!tail && !isAbsolute) {
|
if (!tail && !isAbsolute) {
|
||||||
tail = '.';
|
tail = '.';
|
||||||
@ -443,9 +433,8 @@ posix.resolve = function() {
|
|||||||
// handle relative paths to be safe (might happen when process.cwd() fails)
|
// handle relative paths to be safe (might happen when process.cwd() fails)
|
||||||
|
|
||||||
// Normalize the path
|
// Normalize the path
|
||||||
resolvedPath = normalizeArray(resolvedPath.split('/').filter(function(p) {
|
resolvedPath = normalizeArray(resolvedPath.split('/'),
|
||||||
return !!p;
|
!resolvedAbsolute).join('/');
|
||||||
}), !resolvedAbsolute).join('/');
|
|
||||||
|
|
||||||
return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
|
return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
|
||||||
};
|
};
|
||||||
@ -454,17 +443,10 @@ posix.resolve = function() {
|
|||||||
// posix version
|
// posix version
|
||||||
posix.normalize = function(path) {
|
posix.normalize = function(path) {
|
||||||
var isAbsolute = posix.isAbsolute(path),
|
var isAbsolute = posix.isAbsolute(path),
|
||||||
trailingSlash = path.substr(-1) === '/',
|
trailingSlash = path.substr(-1) === '/';
|
||||||
segments = path.split('/'),
|
|
||||||
nonEmptySegments = [];
|
|
||||||
|
|
||||||
// Normalize the path
|
// Normalize the path
|
||||||
for (var i = 0; i < segments.length; i++) {
|
path = normalizeArray(path.split('/'), !isAbsolute).join('/');
|
||||||
if (segments[i]) {
|
|
||||||
nonEmptySegments.push(segments[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
path = normalizeArray(nonEmptySegments, !isAbsolute).join('/');
|
|
||||||
|
|
||||||
if (!path && !isAbsolute) {
|
if (!path && !isAbsolute) {
|
||||||
path = '.';
|
path = '.';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user