diff options
author | Timothy Gu <timothygu99@gmail.com> | 2017-07-24 03:39:02 +0300 |
---|---|---|
committer | Timothy Gu <timothygu99@gmail.com> | 2017-07-30 14:24:23 +0300 |
commit | 2791761edaf7c3cca41db9c2428bf26d14d8fd01 (patch) | |
tree | 2e08c11a9ccd3d2c6a07b14ef269da60379ce67d /lib/path.js | |
parent | 85add2bf99b754004e26919518846662931ff3a1 (diff) |
path: fix win32 volume-relative paths
`path.resolve()` and `path.join()` are left alone in this commit due to
the lack of clear semantics.
PR-URL: https://github.com/nodejs/node/pull/14440
Fixes: https://github.com/nodejs/node/issues/14405
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Diffstat (limited to 'lib/path.js')
-rw-r--r-- | lib/path.js | 45 |
1 files changed, 25 insertions, 20 deletions
diff --git a/lib/path.js b/lib/path.js index 019843f3eb4..833daf7b461 100644 --- a/lib/path.js +++ b/lib/path.js @@ -908,6 +908,7 @@ const win32 = { extname: function extname(path) { assertPath(path); + var start = 0; var startDot = -1; var startPart = 0; var end = -1; @@ -915,7 +916,20 @@ const win32 = { // Track the state of characters (if any) we see before our first dot and // after any path separator we find var preDotState = 0; - for (var i = path.length - 1; i >= 0; --i) { + + // Check for a drive letter prefix so as not to mistake the following + // path separator as an extra separator at the end of the path that can be + // disregarded + if (path.length >= 2) { + const code = path.charCodeAt(0); + if (path.charCodeAt(1) === 58/*:*/ && + ((code >= 65/*A*/ && code <= 90/*Z*/) || + (code >= 97/*a*/ && code <= 122/*z*/))) { + start = startPart = 2; + } + } + + for (var i = path.length - 1; i >= start; --i) { const code = path.charCodeAt(i); if (code === 47/*/*/ || code === 92/*\*/) { // If we reached a path separator that was not part of a set of path @@ -978,15 +992,12 @@ const win32 = { var len = path.length; var rootEnd = 0; var code = path.charCodeAt(0); - var isAbsolute = false; // Try to match a root if (len > 1) { if (code === 47/*/*/ || code === 92/*\*/) { // Possible UNC root - isAbsolute = true; - code = path.charCodeAt(1); rootEnd = 1; if (code === 47/*/*/ || code === 92/*\*/) { @@ -1045,7 +1056,6 @@ const win32 = { ret.root = ret.dir = path; return ret; } - isAbsolute = true; rootEnd = 3; } } else { @@ -1067,7 +1077,7 @@ const win32 = { ret.root = path.slice(0, rootEnd); var startDot = -1; - var startPart = 0; + var startPart = rootEnd; var end = -1; var matchedSlash = true; var i = path.length - 1; @@ -1116,26 +1126,21 @@ const win32 = { startDot === end - 1 && startDot === startPart + 1)) { if (end !== -1) { - if (startPart === 0 && isAbsolute) - ret.base = ret.name = path.slice(rootEnd, end); - else - ret.base = ret.name = path.slice(startPart, end); + ret.base = ret.name = path.slice(startPart, end); } } else { - if (startPart === 0 && isAbsolute) { - ret.name = path.slice(rootEnd, startDot); - ret.base = path.slice(rootEnd, end); - } else { - ret.name = path.slice(startPart, startDot); - ret.base = path.slice(startPart, end); - } + ret.name = path.slice(startPart, startDot); + ret.base = path.slice(startPart, end); ret.ext = path.slice(startDot, end); } - if (startPart > 0) + // If the directory is the root, use the entire root as the `dir` including + // the trailing slash if any (`C:\abc` -> `C:\`). Otherwise, strip out the + // trailing slash (`C:\abc\def` -> `C:\abc`). + if (startPart > 0 && startPart !== rootEnd) ret.dir = path.slice(0, startPart - 1); - else if (isAbsolute) - ret.dir = path.slice(0, rootEnd); + else + ret.dir = ret.root; return ret; }, |