Skip to content

Commit 0eaf3ff

Browse files
jasonginFishrock123
authored andcommitted
path: fallback to process cwd when resolving drive cwd
The `path.resolve()` function when given just a drive letter such as "C:" tries to get a drive-specific CWD, but that isn't available in cases when the process is not launched via cmd.exe and the process CWD has not been explicitly set on that drive. This change adds a fallback to the process CWD, if the process CWD happens to be on the resolved drive letter. If the process CWD is on another drive, then a drive-specific CWD cannot be resolved and defaults to the drive's root as before. Based on experimentation, the fixed behavior matches that of other similar path resolution implementations on Windows I checked: .NET's `System.IO.Path.GetFullPath()` and Python's `os.path.abspath()`. In the automated path test cases the issue doesn't occur when the tests are run normally from cmd.exe. But it did cause an assertion when running the tests from PowerShell, that is fixed by this change. PR-URL: #8541 Fixes: #7215 Reviewed-By: Bartosz Sosnowski <bartosz@janeasystems.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 9205edc commit 0eaf3ff

File tree

3 files changed

+21
-3
lines changed

3 files changed

+21
-3
lines changed

lib/path.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,10 +169,12 @@ const win32 = {
169169
} else {
170170
// Windows has the concept of drive-specific current working
171171
// directories. If we've resolved a drive letter but not yet an
172-
// absolute path, get cwd for that drive. We're sure the device is not
172+
// absolute path, get cwd for that drive, or the process cwd if
173+
// the drive cwd is not available. We're sure the device is not
173174
// a UNC path at this points, because UNC paths are always absolute.
174-
path = process.env['=' + resolvedDevice];
175-
// Verify that a drive-local cwd was found and that it actually points
175+
path = process.env['=' + resolvedDevice] || process.cwd();
176+
177+
// Verify that a cwd was found and that it actually points
176178
// to our drive. If not, default to the drive's root.
177179
if (path === undefined ||
178180
path.slice(0, 3).toLowerCase() !==

test/fixtures/path-resolve.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Tests resolving a path in the context of a spawned process.
2+
// See https://github.com/nodejs/node/issues/7215
3+
var path = require('path');
4+
console.log(path.resolve(process.argv[2]));

test/parallel/test-path.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22
const common = require('../common');
33
const assert = require('assert');
4+
const child = require('child_process');
45
const path = require('path');
56

67
const f = __filename;
@@ -444,6 +445,17 @@ resolveTests.forEach(function(test) {
444445
});
445446
assert.strictEqual(failures.length, 0, failures.join(''));
446447

448+
if (common.isWindows) {
449+
// Test resolving the current Windows drive letter from a spawned process.
450+
// See https://github.com/nodejs/node/issues/7215
451+
const currentDriveLetter = path.parse(process.cwd()).root.substring(0, 2);
452+
const resolveFixture = path.join(common.fixturesDir, 'path-resolve.js');
453+
var spawnResult = child.spawnSync(
454+
process.argv[0], [resolveFixture, currentDriveLetter]);
455+
var resolvedPath = spawnResult.stdout.toString().trim();
456+
assert.equal(resolvedPath.toLowerCase(), process.cwd().toLowerCase());
457+
}
458+
447459

448460
// path.isAbsolute tests
449461
assert.strictEqual(path.win32.isAbsolute('/'), true);

0 commit comments

Comments
 (0)