| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent c3e1c31 commit efbba60
9 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -702,7 +702,7 @@ Module._findPath = function(request, paths, isMain) { | |||
| 702 | 702 | ||
| 703 | 703 | let exts; | |
| 704 | 704 | const trailingSlash = request.length > 0 && | |
| 705 | - (StringPrototypeCharCodeAt(request, request.length - 1) === CHAR_FORWARD_SLASH || ( | ||
| 705 | + ((StringPrototypeCharCodeAt(request, request.length - 1) === CHAR_FORWARD_SLASH || ( | ||
| 706 | 706 | StringPrototypeCharCodeAt(request, request.length - 1) === CHAR_DOT && | |
| 707 | 707 | ( | |
| 708 | 708 | request.length === 1 || | |
@@ -712,7 +712,18 @@ Module._findPath = function(request, paths, isMain) { | |||
| 712 | 712 | StringPrototypeCharCodeAt(request, request.length - 3) === CHAR_FORWARD_SLASH | |
| 713 | 713 | )) | |
| 714 | 714 | ) | |
| 715 | - )); | ||
| 715 | + )) || (isWindows && ( | ||
| 716 | + StringPrototypeCharCodeAt(request, request.length - 1) === CHAR_BACKWARD_SLASH || ( | ||
| 717 | + StringPrototypeCharCodeAt(request, request.length - 1) === CHAR_DOT && | ||
| 718 | + ( | ||
| 719 | + request.length === 1 || | ||
| 720 | + StringPrototypeCharCodeAt(request, request.length - 2) === CHAR_BACKWARD_SLASH || | ||
| 721 | + (StringPrototypeCharCodeAt(request, request.length - 2) === CHAR_DOT && ( | ||
| 722 | + request.length === 2 || | ||
| 723 | + StringPrototypeCharCodeAt(request, request.length - 3) === CHAR_BACKWARD_SLASH | ||
| 724 | + )) | ||
| 725 | + ) | ||
| 726 | + )))); | ||
| 716 | 727 | ||
| 717 | 728 | const isRelative = StringPrototypeCharCodeAt(request, 0) === CHAR_DOT && | |
| 718 | 729 | ( | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -74,9 +74,7 @@ const { | |||
| 74 | 74 | } = require('internal/errors'); | |
| 75 | 75 | const { | |
| 76 | 76 | CHAR_AMPERSAND, | |
| 77 | - CHAR_BACKWARD_SLASH, | ||
| 78 | 77 | CHAR_EQUAL, | |
| 79 | - CHAR_FORWARD_SLASH, | ||
| 80 | 78 | CHAR_LOWERCASE_A, | |
| 81 | 79 | CHAR_LOWERCASE_Z, | |
| 82 | 80 | CHAR_PERCENT, | |
@@ -1569,13 +1567,6 @@ function pathToFileURL(filepath, options = kEmptyObject) { | |||
| 1569 | 1567 | return outURL; | |
| 1570 | 1568 | } | |
| 1571 | 1569 | let resolved = (windows ?? isWindows) ? path.win32.resolve(filepath) : path.posix.resolve(filepath); | |
| 1572 | - // path.resolve strips trailing slashes so we must add them back | ||
| 1573 | - const filePathLast = StringPrototypeCharCodeAt(filepath, | ||
| 1574 | - filepath.length - 1); | ||
| 1575 | - if ((filePathLast === CHAR_FORWARD_SLASH || | ||
| 1576 | - ((windows ?? isWindows) && filePathLast === CHAR_BACKWARD_SLASH)) && | ||
| 1577 | - resolved[resolved.length - 1] !== path.sep) | ||
| 1578 | - resolved += '/'; | ||
| 1579 | 1570 | ||
| 1580 | 1571 | // Call encodePathChars first to avoid encoding % again for ? and #. | |
| 1581 | 1572 | resolved = encodePathChars(resolved, { windows }); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -190,6 +190,7 @@ const win32 = { | |||
| 190 | 190 | let resolvedDevice = ''; | |
| 191 | 191 | let resolvedTail = ''; | |
| 192 | 192 | let resolvedAbsolute = false; | |
| 193 | + let slashCheck = false; | ||
| 193 | 194 | ||
| 194 | 195 | for (let i = args.length - 1; i >= -1; i--) { | |
| 195 | 196 | let path; | |
@@ -221,6 +222,10 @@ const win32 = { | |||
| 221 | 222 | } | |
| 222 | 223 | } | |
| 223 | 224 | ||
| 225 | + if (i === args.length - 1 && | ||
| 226 | + isPathSeparator(StringPrototypeCharCodeAt(path, path.length - 1))) { | ||
| 227 | + slashCheck = true; | ||
| 228 | + } | ||
| 224 | 229 | const len = path.length; | |
| 225 | 230 | let rootEnd = 0; | |
| 226 | 231 | let device = ''; | |
@@ -268,10 +273,16 @@ const win32 = { | |||
| 268 | 273 | j++; | |
| 269 | 274 | } | |
| 270 | 275 | if (j === len || j !== last) { | |
| 271 | - // We matched a UNC root | ||
| 272 | - device = | ||
| 273 | - `\\\\${firstPart}\\${StringPrototypeSlice(path, last, j)}`; | ||
| 274 | - rootEnd = j; | ||
| 276 | + if (firstPart !== '.' && firstPart !== '?') { | ||
| 277 | + // We matched a UNC root | ||
| 278 | + device = | ||
| 279 | + `\\\\${firstPart}\\${StringPrototypeSlice(path, last, j)}`; | ||
| 280 | + rootEnd = j; | ||
| 281 | + } else { | ||
| 282 | + // We matched a device root (e.g. \\\\.\\PHYSICALDRIVE0) | ||
| 283 | + device = `\\\\${firstPart}`; | ||
| 284 | + rootEnd = 4; | ||
| 285 | + } | ||
| 275 | 286 | } | |
| 276 | 287 | } | |
| 277 | 288 | } | |
@@ -323,9 +334,21 @@ const win32 = { | |||
| 323 | 334 | resolvedTail = normalizeString(resolvedTail, !resolvedAbsolute, '\\', | |
| 324 | 335 | isPathSeparator); | |
| 325 | 336 | ||
| 326 | - return resolvedAbsolute ? | ||
| 327 | - `${resolvedDevice}\\${resolvedTail}` : | ||
| 328 | - `${resolvedDevice}${resolvedTail}` || '.'; | ||
| 337 | + if (!resolvedAbsolute) { | ||
| 338 | + return `${resolvedDevice}${resolvedTail}` || '.'; | ||
| 339 | + } | ||
| 340 | + | ||
| 341 | + if (resolvedTail.length === 0) { | ||
| 342 | + return slashCheck ? `${resolvedDevice}\\` : resolvedDevice; | ||
| 343 | + } | ||
| 344 | + | ||
| 345 | + if (slashCheck) { | ||
| 346 | + return resolvedTail === '\\' ? | ||
| 347 | + `${resolvedDevice}\\` : | ||
| 348 | + `${resolvedDevice}\\${resolvedTail}\\`; | ||
| 349 | + } | ||
| 350 | + | ||
| 351 | + return `${resolvedDevice}\\${resolvedTail}`; | ||
| 329 | 352 | }, | |
| 330 | 353 | ||
| 331 | 354 | /** | |
@@ -381,17 +404,22 @@ const win32 = { | |||
| 381 | 404 | !isPathSeparator(StringPrototypeCharCodeAt(path, j))) { | |
| 382 | 405 | j++; | |
| 383 | 406 | } | |
| 384 | - if (j === len) { | ||
| 385 | - // We matched a UNC root only | ||
| 386 | - // Return the normalized version of the UNC root since there | ||
| 387 | - // is nothing left to process | ||
| 388 | - return `\\\\${firstPart}\\${StringPrototypeSlice(path, last)}\\`; | ||
| 389 | - } | ||
| 390 | - if (j !== last) { | ||
| 391 | - // We matched a UNC root with leftovers | ||
| 392 | - device = | ||
| 393 | - `\\\\${firstPart}\\${StringPrototypeSlice(path, last, j)}`; | ||
| 394 | - rootEnd = j; | ||
| 407 | + if (j === len || j !== last) { | ||
| 408 | + if (firstPart === '.' || firstPart === '?') { | ||
| 409 | + // We matched a device root (e.g. \\\\.\\PHYSICALDRIVE0) | ||
| 410 | + device = `\\\\${firstPart}`; | ||
| 411 | + rootEnd = 4; | ||
| 412 | + } else if (j === len) { | ||
| 413 | + // We matched a UNC root only | ||
| 414 | + // Return the normalized version of the UNC root since there | ||
| 415 | + // is nothing left to process | ||
| 416 | + return `\\\\${firstPart}\\${StringPrototypeSlice(path, last)}\\`; | ||
| 417 | + } else { | ||
| 418 | + // We matched a UNC root with leftovers | ||
| 419 | + device = | ||
| 420 | + `\\\\${firstPart}\\${StringPrototypeSlice(path, last, j)}`; | ||
| 421 | + rootEnd = j; | ||
| 422 | + } | ||
| 395 | 423 | } | |
| 396 | 424 | } | |
| 397 | 425 | } | |
@@ -1162,6 +1190,7 @@ const posix = { | |||
| 1162 | 1190 | resolve(...args) { | |
| 1163 | 1191 | let resolvedPath = ''; | |
| 1164 | 1192 | let resolvedAbsolute = false; | |
| 1193 | + let slashCheck = false; | ||
| 1165 | 1194 | ||
| 1166 | 1195 | for (let i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) { | |
| 1167 | 1196 | const path = i >= 0 ? args[i] : posixCwd(); | |
@@ -1171,8 +1200,17 @@ const posix = { | |||
| 1171 | 1200 | if (path.length === 0) { | |
| 1172 | 1201 | continue; | |
| 1173 | 1202 | } | |
| 1203 | + if (i === args.length - 1 && | ||
| 1204 | + isPosixPathSeparator(StringPrototypeCharCodeAt(path, | ||
| 1205 | + path.length - 1))) { | ||
| 1206 | + slashCheck = true; | ||
| 1207 | + } | ||
| 1174 | 1208 | ||
| 1175 | - resolvedPath = `${path}/${resolvedPath}`; | ||
| 1209 | + if (resolvedPath.length !== 0) { | ||
| 1210 | + resolvedPath = `${path}/${resolvedPath}`; | ||
| 1211 | + } else { | ||
| 1212 | + resolvedPath = path; | ||
| 1213 | + } | ||
| 1176 | 1214 | resolvedAbsolute = | |
| 1177 | 1215 | StringPrototypeCharCodeAt(path, 0) === CHAR_FORWARD_SLASH; | |
| 1178 | 1216 | } | |
@@ -1184,10 +1222,20 @@ const posix = { | |||
| 1184 | 1222 | resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute, '/', | |
| 1185 | 1223 | isPosixPathSeparator); | |
| 1186 | 1224 | ||
| 1187 | - if (resolvedAbsolute) { | ||
| 1188 | - return `/${resolvedPath}`; | ||
| 1225 | + if (!resolvedAbsolute) { | ||
| 1226 | + if (resolvedPath.length === 0) { | ||
| 1227 | + return '.'; | ||
| 1228 | + } | ||
| 1229 | + if (slashCheck) { | ||
| 1230 | + return `${resolvedPath}/`; | ||
| 1231 | + } | ||
| 1232 | + return resolvedPath; | ||
| 1233 | + } | ||
| 1234 | + | ||
| 1235 | + if (resolvedPath.length === 0 || resolvedPath === '/') { | ||
| 1236 | + return '/'; | ||
| 1189 | 1237 | } | |
| 1190 | - return resolvedPath.length > 0 ? resolvedPath : '.'; | ||
| 1238 | + return slashCheck ? `/${resolvedPath}/` : `/${resolvedPath}`; | ||
| 1191 | 1239 | }, | |
| 1192 | 1240 | ||
| 1193 | 1241 | /** | |
@@ -1271,11 +1319,35 @@ const posix = { | |||
| 1271 | 1319 | if (from === to) | |
| 1272 | 1320 | return ''; | |
| 1273 | 1321 | ||
| 1274 | - const fromStart = 1; | ||
| 1275 | - const fromEnd = from.length; | ||
| 1322 | + // Trim any leading slashes | ||
| 1323 | + let fromStart = 0; | ||
| 1324 | + while (fromStart < from.length && | ||
| 1325 | + StringPrototypeCharCodeAt(from, fromStart) === CHAR_FORWARD_SLASH) { | ||
| 1326 | + fromStart++; | ||
| 1327 | + } | ||
| 1328 | + // Trim trailing slashes | ||
| 1329 | + let fromEnd = from.length; | ||
| 1330 | + while ( | ||
| 1331 | + fromEnd - 1 > fromStart && | ||
| 1332 | + StringPrototypeCharCodeAt(from, fromEnd - 1) === CHAR_FORWARD_SLASH | ||
| 1333 | + ) { | ||
| 1334 | + fromEnd--; | ||
| 1335 | + } | ||
| 1276 | 1336 | const fromLen = fromEnd - fromStart; | |
| 1277 | - const toStart = 1; | ||
| 1278 | - const toLen = to.length - toStart; | ||
| 1337 | + | ||
| 1338 | + // Trim any leading slashes | ||
| 1339 | + let toStart = 0; | ||
| 1340 | + while (toStart < to.length && | ||
| 1341 | + StringPrototypeCharCodeAt(to, toStart) === CHAR_FORWARD_SLASH) { | ||
| 1342 | + toStart++; | ||
| 1343 | + } | ||
| 1344 | + // Trim trailing slashes | ||
| 1345 | + let toEnd = to.length; | ||
| 1346 | + while (toEnd - 1 > toStart && | ||
| 1347 | + StringPrototypeCharCodeAt(to, toEnd - 1) === CHAR_FORWARD_SLASH) { | ||
| 1348 | + toEnd--; | ||
| 1349 | + } | ||
| 1350 | + const toLen = toEnd - toStart; | ||
| 1279 | 1351 | ||
| 1280 | 1352 | // Compare paths to find the longest common path from root | |
| 1281 | 1353 | const length = (fromLen < toLen ? fromLen : toLen); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -97,6 +97,7 @@ std::string PathResolve(Environment* env, | |||
| 97 | 97 | std::string resolvedDevice = ""; | |
| 98 | 98 | std::string resolvedTail = ""; | |
| 99 | 99 | bool resolvedAbsolute = false; | |
| 100 | + bool slashCheck = false; | ||
| 100 | 101 | const size_t numArgs = paths.size(); | |
| 101 | 102 | auto cwd = env->GetCwd(env->exec_path()); | |
| 102 | 103 | ||
@@ -126,6 +127,10 @@ std::string PathResolve(Environment* env, | |||
| 126 | 127 | } | |
| 127 | 128 | } | |
| 128 | 129 | ||
| 130 | + if (static_cast<size_t>(i) == numArgs - 1 && | ||
| 131 | + IsPathSeparator(path[path.length() - 1])) { | ||
| 132 | + slashCheck = true; | ||
| 133 | + } | ||
| 129 | 134 | const size_t len = path.length(); | |
| 130 | 135 | int rootEnd = 0; | |
| 131 | 136 | std::string device = ""; | |
@@ -170,9 +175,16 @@ std::string PathResolve(Environment* env, | |||
| 170 | 175 | j++; | |
| 171 | 176 | } | |
| 172 | 177 | if (j == len || j != last) { | |
| 173 | - // We matched a UNC root | ||
| 174 | - device = "\\\\" + firstPart + "\\" + path.substr(last, j - last); | ||
| 175 | - rootEnd = j; | ||
| 178 | + if (firstPart != "." && firstPart != "?") { | ||
| 179 | + // We matched a UNC root | ||
| 180 | + device = | ||
| 181 | + "\\\\" + firstPart + "\\" + path.substr(last, j - last); | ||
| 182 | + rootEnd = j; | ||
| 183 | + } else { | ||
| 184 | + // We matched a device root (e.g. \\\\.\\PHYSICALDRIVE0) | ||
| 185 | + device = "\\\\" + firstPart; | ||
| 186 | + rootEnd = 4; | ||
| 187 | + } | ||
| 176 | 188 | } | |
| 177 | 189 | } | |
| 178 | 190 | } | |
@@ -220,15 +232,27 @@ std::string PathResolve(Environment* env, | |||
| 220 | 232 | // Normalize the tail path | |
| 221 | 233 | resolvedTail = NormalizeString(resolvedTail, !resolvedAbsolute, "\\"); | |
| 222 | 234 | ||
| 223 | - if (resolvedAbsolute) { | ||
| 224 | - return resolvedDevice + "\\" + resolvedTail; | ||
| 235 | + if (!resolvedAbsolute) { | ||
| 236 | + if (!resolvedDevice.empty() || !resolvedTail.empty()) { | ||
| 237 | + return resolvedDevice + resolvedTail; | ||
| 238 | + } | ||
| 239 | + return "."; | ||
| 225 | 240 | } | |
| 226 | 241 | ||
| 227 | - if (!resolvedDevice.empty() || !resolvedTail.empty()) { | ||
| 228 | - return resolvedDevice + resolvedTail; | ||
| 242 | + if (resolvedTail.empty()) { | ||
| 243 | + if (slashCheck) { | ||
| 244 | + return resolvedDevice + "\\"; | ||
| 245 | + } | ||
| 246 | + return resolvedDevice; | ||
| 229 | 247 | } | |
| 230 | 248 | ||
| 231 | - return "."; | ||
| 249 | + if (slashCheck) { | ||
| 250 | + if (resolvedTail == "\\") { | ||
| 251 | + return resolvedDevice + "\\"; | ||
| 252 | + } | ||
| 253 | + return resolvedDevice + "\\" + resolvedTail + "\\"; | ||
| 254 | + } | ||
| 255 | + return resolvedDevice + "\\" + resolvedTail; | ||
| 232 | 256 | } | |
| 233 | 257 | #else // _WIN32 | |
| 234 | 258 | std::string PathResolve(Environment* env, | |
@@ -237,10 +261,15 @@ std::string PathResolve(Environment* env, | |||
| 237 | 261 | bool resolvedAbsolute = false; | |
| 238 | 262 | auto cwd = env->GetCwd(env->exec_path()); | |
| 239 | 263 | const size_t numArgs = paths.size(); | |
| 264 | + bool slashCheck = false; | ||
| 240 | 265 | ||
| 241 | 266 | for (int i = numArgs - 1; i >= -1 && !resolvedAbsolute; i--) { | |
| 242 | 267 | const std::string& path = (i >= 0) ? std::string(paths[i]) : cwd; | |
| 243 | 268 | ||
| 269 | + if (static_cast<size_t>(i) == numArgs - 1 && path.back() == '/') { | ||
| 270 | + slashCheck = true; | ||
| 271 | + } | ||
| 272 | + | ||
| 244 | 273 | if (!path.empty()) { | |
| 245 | 274 | resolvedPath = std::string(path) + "/" + resolvedPath; | |
| 246 | 275 | ||
@@ -254,15 +283,21 @@ std::string PathResolve(Environment* env, | |||
| 254 | 283 | // Normalize the path | |
| 255 | 284 | auto normalizedPath = NormalizeString(resolvedPath, !resolvedAbsolute, "/"); | |
| 256 | 285 | ||
| 257 | - if (resolvedAbsolute) { | ||
| 258 | - return "/" + normalizedPath; | ||
| 286 | + if (!resolvedAbsolute) { | ||
| 287 | + if (normalizedPath.empty()) { | ||
| 288 | + return "."; | ||
| 289 | + } | ||
| 290 | + if (slashCheck) { | ||
| 291 | + return normalizedPath + "/"; | ||
| 292 | + } | ||
| 293 | + return normalizedPath; | ||
| 259 | 294 | } | |
| 260 | 295 | ||
| 261 | - if (normalizedPath.empty()) { | ||
| 262 | - return "."; | ||
| 296 | + if (normalizedPath.empty() || normalizedPath == "/") { | ||
| 297 | + return "/"; | ||
| 263 | 298 | } | |
| 264 | 299 | ||
| 265 | - return normalizedPath; | ||
| 300 | + return slashCheck ? "/" + normalizedPath + "/" : "/" + normalizedPath; | ||
| 266 | 301 | } | |
| 267 | 302 | #endif // _WIN32 | |
| 268 | 303 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -25,26 +25,28 @@ TEST_F(PathTest, PathResolve) { | |||
| 25 | 25 | "d:\\e.exe"); | |
| 26 | 26 | EXPECT_EQ(PathResolve(*env, {"c:/ignore", "c:/some/file"}), "c:\\some\\file"); | |
| 27 | 27 | EXPECT_EQ(PathResolve(*env, {"d:/ignore", "d:some/dir//"}), | |
| 28 | - "d:\\ignore\\some\\dir"); | ||
| 28 | + "d:\\ignore\\some\\dir\\"); | ||
| 29 | 29 | EXPECT_EQ(PathResolve(*env, {"."}), cwd); | |
| 30 | 30 | EXPECT_EQ(PathResolve(*env, {"//server/share", "..", "relative\\"}), | |
| 31 | - "\\\\server\\share\\relative"); | ||
| 31 | + "\\\\server\\share\\relative\\"); | ||
| 32 | 32 | EXPECT_EQ(PathResolve(*env, {"c:/", "//"}), "c:\\"); | |
| 33 | 33 | EXPECT_EQ(PathResolve(*env, {"c:/", "//dir"}), "c:\\dir"); | |
| 34 | - EXPECT_EQ(PathResolve(*env, {"c:/", "//server/share"}), | ||
| 35 | - "\\\\server\\share\\"); | ||
| 36 | - EXPECT_EQ(PathResolve(*env, {"c:/", "//server//share"}), | ||
| 37 | - "\\\\server\\share\\"); | ||
| 34 | + EXPECT_EQ(PathResolve(*env, {"c:/", "//server/share"}), "\\\\server\\share"); | ||
| 35 | + EXPECT_EQ(PathResolve(*env, {"c:/", "//server//share"}), "\\\\server\\share"); | ||
| 38 | 36 | EXPECT_EQ(PathResolve(*env, {"c:/", "///some//dir"}), "c:\\some\\dir"); | |
| 39 | 37 | EXPECT_EQ( | |
| 40 | 38 | PathResolve(*env, {"C:\\foo\\tmp.3\\", "..\\tmp.3\\cycles\\root.js"}), | |
| 41 | 39 | "C:\\foo\\tmp.3\\cycles\\root.js"); | |
| 40 | + EXPECT_EQ(PathResolve(*env, {"\\\\.\\PHYSICALDRIVE0"}), | ||
| 41 | + "\\\\.\\PHYSICALDRIVE0"); | ||
| 42 | + EXPECT_EQ(PathResolve(*env, {"\\\\?\\PHYSICALDRIVE0"}), | ||
| 43 | + "\\\\?\\PHYSICALDRIVE0"); | ||
| 42 | 44 | #else | |
| 43 | - EXPECT_EQ(PathResolve(*env, {"/var/lib", "../", "file/"}), "/var/file"); | ||
| 44 | - EXPECT_EQ(PathResolve(*env, {"/var/lib", "/../", "file/"}), "/file"); | ||
| 45 | + EXPECT_EQ(PathResolve(*env, {"/var/lib", "../", "file/"}), "/var/file/"); | ||
| 46 | + EXPECT_EQ(PathResolve(*env, {"/var/lib", "/../", "file/"}), "/file/"); | ||
| 45 | 47 | EXPECT_EQ(PathResolve(*env, {"a/b/c/", "../../.."}), cwd); | |
| 46 | 48 | EXPECT_EQ(PathResolve(*env, {"."}), cwd); | |
| 47 | - EXPECT_EQ(PathResolve(*env, {"/some/dir", ".", "/absolute/"}), "/absolute"); | ||
| 49 | + EXPECT_EQ(PathResolve(*env, {"/some/dir", ".", "/absolute/"}), "/absolute/"); | ||
| 48 | 50 | EXPECT_EQ(PathResolve(*env, {"/foo/tmp.3/", "../tmp.3/cycles/root.js"}), | |
| 49 | 51 | "/foo/tmp.3/cycles/root.js"); | |
| 50 | 52 | #endif | |
| Back | FazBrowse Home | New Git URL |
0 commit comments