From af15b4e45a7affa911307b0ad20f6b2a0a67df9d Mon Sep 17 00:00:00 2001 From: Bert Belder Date: Wed, 5 Jan 2011 16:32:04 +0100 Subject: [PATCH] Remove path module dependency from url module Now the path module can be adapted to support windows paths without breaking the url module. It also allows the undocumented keepBlanks flag to be removed from path.join and path.normalizeArray. --- lib/url.js | 47 ++++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/lib/url.js b/lib/url.js index b8c1105a9f2..d497116f58a 100644 --- a/lib/url.js +++ b/lib/url.js @@ -24,7 +24,6 @@ var protocolPattern = /^([a-z0-9]+:)/, 'gopher:': true, 'file:': true }, - path = require('path'), // internal module, guaranteed to be loaded already. querystring = require('querystring'); function urlParse(url, parseQueryString, slashesDenoteHost) { @@ -280,7 +279,6 @@ function urlResolveObject(source, relative) { return source; } - // resolve dots. // if a url ENDs in . or .., then it must get a trailing slash. // however, if it ends in anything else non-slashy, // then it must NOT get a trailing slash. @@ -289,27 +287,34 @@ function urlResolveObject(source, relative) { (source.host || relative.host) && (last === '.' || last === '..') || last === ''); - // Figure out if this has to end up as an absolute url, - // or should continue to be relative. - srcPath = path.normalizeArray(srcPath, true); - if (srcPath.length === 1 && srcPath[0] === '.') srcPath = []; - if (mustEndAbs || removeAllDots) { - // all dots must go. - var dirs = []; - srcPath.forEach(function(dir, i) { - if (dir === '..') { - dirs.pop(); - } else if (dir !== '.') { - dirs.push(dir); - } - }); - - if (mustEndAbs && dirs[0] !== '' && - (!dirs[0] || dirs[0].charAt(0) !== '/')) { - dirs.unshift(''); + // strip single dots, resolve double dots to parent dir + // if the path tries to go above the root, `up` ends up > 0 + var up = 0; + for (var i = srcPath.length; i >= 0; i--) { + last = srcPath[i]; + if (last == '.') { + srcPath.splice(i, 1); + } else if (last === '..') { + srcPath.splice(i, 1); + up++; + } else if (up) { + srcPath.splice(i, 1); + up--; } - srcPath = dirs; } + + // if the path is allowed to go above the root, restore leading ..s + if (!mustEndAbs && !removeAllDots) { + for ( ; up--; up) { + srcPath.unshift('..'); + } + } + + if (mustEndAbs && srcPath[0] !== '' && + (!srcPath[0] || srcPath[0].charAt(0) !== '/')) { + srcPath.unshift(''); + } + if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) { srcPath.push(''); }