diff --git a/lib/path.js b/lib/path.js index 248809b2e2f70b..098416adfe1a3a 100644 --- a/lib/path.js +++ b/lib/path.js @@ -40,6 +40,15 @@ function assertPath(path) { } } +function isPathSeparator(code) { + return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH; +} + +function isWindowsDeviceRoot(code) { + return code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z || + code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z; +} + // Resolves . and .. elements in a path with directory names function normalizeStringWin32(path, allowAboveRoot) { var res = ''; @@ -50,11 +59,12 @@ function normalizeStringWin32(path, allowAboveRoot) { for (var i = 0; i <= path.length; ++i) { if (i < path.length) code = path.charCodeAt(i); - else if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) + else if (isPathSeparator(code)) break; else code = CHAR_FORWARD_SLASH; - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) { + + if (isPathSeparator(code)) { if (lastSlash === i - 1 || dots === 1) { // NOOP } else if (lastSlash !== i - 1 && dots === 2) { @@ -228,28 +238,26 @@ const win32 = { var len = path.length; var rootEnd = 0; - var code = path.charCodeAt(0); var device = ''; var isAbsolute = false; + const code = path.charCodeAt(0); // Try to match a root if (len > 1) { - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) { + if (isPathSeparator(code)) { // Possible UNC root // If we started with a separator, we know we at least have an // absolute path of some kind (UNC or otherwise) isAbsolute = true; - code = path.charCodeAt(1); - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) { + if (isPathSeparator(path.charCodeAt(1))) { // Matched double path separator at beginning var j = 2; var last = j; // Match 1 or more non-path separators for (; j < len; ++j) { - code = path.charCodeAt(j); - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) + if (isPathSeparator(path.charCodeAt(j))) break; } if (j < len && j !== last) { @@ -258,8 +266,7 @@ const win32 = { last = j; // Match 1 or more path separators for (; j < len; ++j) { - code = path.charCodeAt(j); - if (code !== CHAR_FORWARD_SLASH && code !== CHAR_BACKWARD_SLASH) + if (!isPathSeparator(path.charCodeAt(j))) break; } if (j < len && j !== last) { @@ -267,11 +274,7 @@ const win32 = { last = j; // Match 1 or more non-path separators for (; j < len; ++j) { - code = path.charCodeAt(j); - const isPathSeparator = - code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH; - - if (isPathSeparator) + if (isPathSeparator(path.charCodeAt(j))) break; } if (j === len) { @@ -290,16 +293,14 @@ const win32 = { } else { rootEnd = 1; } - } else if ((code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z) || - (code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z)) { + } else if (isWindowsDeviceRoot(code)) { // Possible device root if (path.charCodeAt(1) === CHAR_COLON) { device = path.slice(0, 2); rootEnd = 2; if (len > 2) { - code = path.charCodeAt(2); - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) { + if (isPathSeparator(path.charCodeAt(2))) { // Treat separator following drive name as an absolute path // indicator isAbsolute = true; @@ -308,7 +309,7 @@ const win32 = { } } } - } else if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) { + } else if (isPathSeparator(code)) { // `path` contains just a path separator rootEnd = 1; isAbsolute = true; @@ -351,28 +352,26 @@ const win32 = { if (len === 0) return '.'; var rootEnd = 0; - var code = path.charCodeAt(0); var device; var isAbsolute = false; + const code = path.charCodeAt(0); // Try to match a root if (len > 1) { - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) { + if (isPathSeparator(code)) { // Possible UNC root // If we started with a separator, we know we at least have an absolute // path of some kind (UNC or otherwise) isAbsolute = true; - code = path.charCodeAt(1); - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) { + if (isPathSeparator(path.charCodeAt(1))) { // Matched double path separator at beginning var j = 2; var last = j; // Match 1 or more non-path separators for (; j < len; ++j) { - code = path.charCodeAt(j); - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) + if (isPathSeparator(path.charCodeAt(j))) break; } if (j < len && j !== last) { @@ -381,8 +380,7 @@ const win32 = { last = j; // Match 1 or more path separators for (; j < len; ++j) { - code = path.charCodeAt(j); - if (code !== CHAR_FORWARD_SLASH && code !== CHAR_BACKWARD_SLASH) + if (!isPathSeparator(path.charCodeAt(j))) break; } if (j < len && j !== last) { @@ -390,8 +388,7 @@ const win32 = { last = j; // Match 1 or more non-path separators for (; j < len; ++j) { - code = path.charCodeAt(j); - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) + if (isPathSeparator(path.charCodeAt(j))) break; } if (j === len) { @@ -411,16 +408,14 @@ const win32 = { } else { rootEnd = 1; } - } else if ((code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z) || - (code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z)) { + } else if (isWindowsDeviceRoot(code)) { // Possible device root if (path.charCodeAt(1) === CHAR_COLON) { device = path.slice(0, 2); rootEnd = 2; if (len > 2) { - code = path.charCodeAt(2); - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) { + if (isPathSeparator(path.charCodeAt(2))) { // Treat separator following drive name as an absolute path // indicator isAbsolute = true; @@ -429,15 +424,12 @@ const win32 = { } } } - } else if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) { + } else if (isPathSeparator(code)) { // `path` contains just a path separator, exit early to avoid unnecessary // work return '\\'; } - code = path.charCodeAt(len - 1); - var trailingSeparator = - (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH); var tail; if (rootEnd < len) tail = normalizeStringWin32(path.slice(rootEnd), !isAbsolute); @@ -445,7 +437,7 @@ const win32 = { tail = ''; if (tail.length === 0 && !isAbsolute) tail = '.'; - if (tail.length > 0 && trailingSeparator) + if (tail.length > 0 && isPathSeparator(path.charCodeAt(len - 1))) tail += '\\'; if (device === undefined) { if (isAbsolute) { @@ -476,16 +468,15 @@ const win32 = { const len = path.length; if (len === 0) return false; - var code = path.charCodeAt(0); - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) { + + const code = path.charCodeAt(0); + if (isPathSeparator(code)) { return true; - } else if ((code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z) || - (code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z)) { + } else if (isWindowsDeviceRoot(code)) { // Possible device root if (len > 2 && path.charCodeAt(1) === CHAR_COLON) { - code = path.charCodeAt(2); - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) + if (isPathSeparator(path.charCodeAt(2))) return true; } } @@ -528,17 +519,14 @@ const win32 = { // path.join('//server', 'share') -> '\\\\server\\share\\') var needsReplace = true; var slashCount = 0; - var code = firstPart.charCodeAt(0); - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) { + if (isPathSeparator(firstPart.charCodeAt(0))) { ++slashCount; const firstLen = firstPart.length; if (firstLen > 1) { - code = firstPart.charCodeAt(1); - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) { + if (isPathSeparator(firstPart.charCodeAt(1))) { ++slashCount; if (firstLen > 2) { - code = firstPart.charCodeAt(2); - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) + if (isPathSeparator(firstPart.charCodeAt(2))) ++slashCount; else { // We matched a UNC path in the first part @@ -551,8 +539,7 @@ const win32 = { if (needsReplace) { // Find any more consecutive slashes we need to replace for (; slashCount < joined.length; ++slashCount) { - code = joined.charCodeAt(slashCount); - if (code !== CHAR_FORWARD_SLASH && code !== CHAR_BACKWARD_SLASH) + if (!isPathSeparator(joined.charCodeAt(slashCount))) break; } @@ -699,19 +686,17 @@ const win32 = { const resolvedPath = win32.resolve(path); if (resolvedPath.length >= 3) { - var code = resolvedPath.charCodeAt(0); - if (code === CHAR_BACKWARD_SLASH) { + if (resolvedPath.charCodeAt(0) === CHAR_BACKWARD_SLASH) { // Possible UNC root if (resolvedPath.charCodeAt(1) === CHAR_BACKWARD_SLASH) { - code = resolvedPath.charCodeAt(2); + const code = resolvedPath.charCodeAt(2); if (code !== CHAR_QUESTION_MARK && code !== CHAR_DOT) { // Matched non-long UNC root, convert the path to a long UNC path return '\\\\?\\UNC\\' + resolvedPath.slice(2); } } - } else if ((code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z) || - (code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z)) { + } else if (isWindowsDeviceRoot(resolvedPath.charCodeAt(0))) { // Possible device root if (resolvedPath.charCodeAt(1) === CHAR_COLON && @@ -734,24 +719,22 @@ const win32 = { var end = -1; var matchedSlash = true; var offset = 0; - var code = path.charCodeAt(0); + const code = path.charCodeAt(0); // Try to match a root if (len > 1) { - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) { + if (isPathSeparator(code)) { // Possible UNC root rootEnd = offset = 1; - code = path.charCodeAt(1); - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) { + if (isPathSeparator(path.charCodeAt(1))) { // Matched double path separator at beginning var j = 2; var last = j; // Match 1 or more non-path separators for (; j < len; ++j) { - code = path.charCodeAt(j); - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) + if (isPathSeparator(path.charCodeAt(j))) break; } if (j < len && j !== last) { @@ -759,8 +742,7 @@ const win32 = { last = j; // Match 1 or more path separators for (; j < len; ++j) { - code = path.charCodeAt(j); - if (code !== CHAR_FORWARD_SLASH && code !== CHAR_BACKWARD_SLASH) + if (!isPathSeparator(path.charCodeAt(j))) break; } if (j < len && j !== last) { @@ -768,8 +750,7 @@ const win32 = { last = j; // Match 1 or more non-path separators for (; j < len; ++j) { - code = path.charCodeAt(j); - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) + if (isPathSeparator(path.charCodeAt(j))) break; } if (j === len) { @@ -786,28 +767,25 @@ const win32 = { } } } - } else if ((code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z) || - (code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z)) { + } else if (isWindowsDeviceRoot(code)) { // Possible device root if (path.charCodeAt(1) === CHAR_COLON) { rootEnd = offset = 2; if (len > 2) { - code = path.charCodeAt(2); - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) + if (isPathSeparator(path.charCodeAt(2))) rootEnd = offset = 3; } } } - } else if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) { + } else if (isPathSeparator(code)) { // `path` contains just a path separator, exit early to avoid // unnecessary work return path; } for (var i = len - 1; i >= offset; --i) { - code = path.charCodeAt(i); - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) { + if (isPathSeparator(path.charCodeAt(i))) { if (!matchedSlash) { end = i; break; @@ -842,8 +820,7 @@ const win32 = { // disregarded if (path.length >= 2) { const drive = path.charCodeAt(0); - if ((drive >= CHAR_UPPERCASE_A && drive <= CHAR_UPPERCASE_Z) || - (drive >= CHAR_LOWERCASE_A && drive <= CHAR_LOWERCASE_Z)) { + if (isWindowsDeviceRoot(drive)) { if (path.charCodeAt(1) === CHAR_COLON) start = 2; } @@ -856,7 +833,7 @@ const win32 = { var firstNonSlashEnd = -1; for (i = path.length - 1; i >= start; --i) { const code = path.charCodeAt(i); - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) { + if (isPathSeparator(code)) { // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now if (!matchedSlash) { @@ -895,8 +872,7 @@ const win32 = { return path.slice(start, end); } else { for (i = path.length - 1; i >= start; --i) { - const code = path.charCodeAt(i); - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) { + if (isPathSeparator(path.charCodeAt(i))) { // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now if (!matchedSlash) { @@ -932,18 +908,16 @@ const win32 = { // 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) === CHAR_COLON && - ((code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z) || - (code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z))) { - start = startPart = 2; - } + + if (path.length >= 2 && + path.charCodeAt(1) === CHAR_COLON && + isWindowsDeviceRoot(path.charCodeAt(0))) { + start = startPart = 2; } for (var i = path.length - 1; i >= start; --i) { const code = path.charCodeAt(i); - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) { + if (isPathSeparator(code)) { // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now if (!matchedSlash) { @@ -1003,23 +977,21 @@ const win32 = { var len = path.length; var rootEnd = 0; - var code = path.charCodeAt(0); + let code = path.charCodeAt(0); // Try to match a root if (len > 1) { - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) { + if (isPathSeparator(code)) { // Possible UNC root - code = path.charCodeAt(1); rootEnd = 1; - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) { + if (isPathSeparator(path.charCodeAt(1))) { // Matched double path separator at beginning var j = 2; var last = j; // Match 1 or more non-path separators for (; j < len; ++j) { - code = path.charCodeAt(j); - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) + if (isPathSeparator(path.charCodeAt(j))) break; } if (j < len && j !== last) { @@ -1027,8 +999,7 @@ const win32 = { last = j; // Match 1 or more path separators for (; j < len; ++j) { - code = path.charCodeAt(j); - if (code !== CHAR_FORWARD_SLASH && code !== CHAR_BACKWARD_SLASH) + if (!isPathSeparator(path.charCodeAt(j))) break; } if (j < len && j !== last) { @@ -1036,8 +1007,7 @@ const win32 = { last = j; // Match 1 or more non-path separators for (; j < len; ++j) { - code = path.charCodeAt(j); - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) + if (isPathSeparator(path.charCodeAt(j))) break; } if (j === len) { @@ -1052,15 +1022,13 @@ const win32 = { } } } - } else if ((code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z) || - (code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z)) { + } else if (isWindowsDeviceRoot(code)) { // Possible device root if (path.charCodeAt(1) === CHAR_COLON) { rootEnd = 2; if (len > 2) { - code = path.charCodeAt(2); - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) { + if (isPathSeparator(path.charCodeAt(2))) { if (len === 3) { // `path` contains just a drive root, exit early to avoid // unnecessary work @@ -1077,7 +1045,7 @@ const win32 = { } } } - } else if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) { + } else if (isPathSeparator(code)) { // `path` contains just a path separator, exit early to avoid // unnecessary work ret.root = ret.dir = path; @@ -1100,7 +1068,7 @@ const win32 = { // Get non-dir info for (; i >= rootEnd; --i) { code = path.charCodeAt(i); - if (code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH) { + if (isPathSeparator(code)) { // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now if (!matchedSlash) { @@ -1363,13 +1331,11 @@ const posix = { assertPath(path); if (path.length === 0) return '.'; - var code = path.charCodeAt(0); - var hasRoot = (code === CHAR_FORWARD_SLASH); + const hasRoot = path.charCodeAt(0) === CHAR_FORWARD_SLASH; var end = -1; var matchedSlash = true; for (var i = path.length - 1; i >= 1; --i) { - code = path.charCodeAt(i); - if (code === CHAR_FORWARD_SLASH) { + if (path.charCodeAt(i) === CHAR_FORWARD_SLASH) { if (!matchedSlash) { end = i; break; @@ -1534,8 +1500,7 @@ const posix = { var ret = { root: '', dir: '', base: '', ext: '', name: '' }; if (path.length === 0) return ret; - var code = path.charCodeAt(0); - var isAbsolute = (code === CHAR_FORWARD_SLASH); + var isAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH; var start; if (isAbsolute) { ret.root = '/'; @@ -1555,7 +1520,7 @@ const posix = { // Get non-dir info for (; i >= start; --i) { - code = path.charCodeAt(i); + const code = path.charCodeAt(i); if (code === CHAR_FORWARD_SLASH) { // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now