Skip to content

Commit 6639edd

Browse files
committed
[Fix] homedir: fix operator precedence bug with HOMEDRIVE/HOMEPATH concatenation
1 parent 8509a67 commit 6639edd

2 files changed

Lines changed: 103 additions & 1 deletion

File tree

lib/homedir.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,14 @@ module.exports = os.homedir || function homedir() {
99
var user = process.env.LOGNAME || process.env.USER || process.env.LNAME || process.env.USERNAME;
1010

1111
if (process.platform === 'win32') {
12-
return process.env.USERPROFILE || process.env.HOMEDRIVE + process.env.HOMEPATH || home || null;
12+
return process.env.USERPROFILE
13+
|| (
14+
process.env.HOMEDRIVE
15+
&& process.env.HOMEPATH
16+
&& (process.env.HOMEDRIVE + process.env.HOMEPATH)
17+
)
18+
|| home
19+
|| null;
1320
}
1421

1522
if (process.platform === 'darwin') {

test/homedir.js

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
'use strict';
2+
3+
var os = require('os');
4+
var test = require('tape');
5+
var mockProperty = require('mock-property');
6+
7+
var envKeys = ['HOME', 'USERPROFILE', 'HOMEDRIVE', 'HOMEPATH', 'LOGNAME', 'USER', 'LNAME', 'USERNAME'];
8+
9+
function clearEnv(t) {
10+
for (var i = 0; i < envKeys.length; i++) {
11+
t.teardown(mockProperty(process.env, envKeys[i], { 'delete': true }));
12+
}
13+
}
14+
15+
function getFallback(t) {
16+
t.teardown(mockProperty(os, 'homedir', { value: undefined }));
17+
18+
var homedirPath = require.resolve('../lib/homedir');
19+
t.teardown(mockProperty(require.cache, homedirPath, { 'delete': true }));
20+
21+
return require('../lib/homedir');
22+
}
23+
24+
test('homedir fallback', function (t) {
25+
t.test('win32: HOMEDRIVE without HOMEPATH does not produce a false concatenation', function (st) {
26+
clearEnv(st);
27+
st.teardown(mockProperty(process, 'platform', { value: 'win32' }));
28+
29+
var homedir = getFallback(st);
30+
31+
st.teardown(mockProperty(process.env, 'HOMEDRIVE', { value: 'C:' }));
32+
33+
st.equal(homedir(), null, 'returns null when only HOMEDRIVE is set');
34+
35+
st.end();
36+
});
37+
38+
t.test('win32: HOMEPATH without HOMEDRIVE does not produce a false concatenation', function (st) {
39+
clearEnv(st);
40+
st.teardown(mockProperty(process, 'platform', { value: 'win32' }));
41+
42+
var homedir = getFallback(st);
43+
44+
st.teardown(mockProperty(process.env, 'HOMEPATH', { value: '\\Users\\foo' }));
45+
46+
st.equal(homedir(), null, 'returns null when only HOMEPATH is set');
47+
48+
st.end();
49+
});
50+
51+
t.test('win32: HOMEDRIVE + HOMEPATH both set returns concatenation', function (st) {
52+
clearEnv(st);
53+
st.teardown(mockProperty(process, 'platform', { value: 'win32' }));
54+
55+
var homedir = getFallback(st);
56+
57+
st.teardown(mockProperty(process.env, 'HOMEDRIVE', { value: 'C:' }));
58+
st.teardown(mockProperty(process.env, 'HOMEPATH', { value: '\\Users\\foo' }));
59+
60+
st.equal(homedir(), 'C:\\Users\\foo', 'returns concatenated drive and path');
61+
62+
st.end();
63+
});
64+
65+
t.test('win32: USERPROFILE takes precedence over HOMEDRIVE+HOMEPATH', function (st) {
66+
clearEnv(st);
67+
st.teardown(mockProperty(process, 'platform', { value: 'win32' }));
68+
69+
var homedir = getFallback(st);
70+
71+
st.teardown(mockProperty(process.env, 'USERPROFILE', { value: 'C:\\Users\\bar' }));
72+
st.teardown(mockProperty(process.env, 'HOMEDRIVE', { value: 'C:' }));
73+
st.teardown(mockProperty(process.env, 'HOMEPATH', { value: '\\Users\\foo' }));
74+
75+
st.equal(homedir(), 'C:\\Users\\bar', 'returns USERPROFILE');
76+
77+
st.end();
78+
});
79+
80+
t.test('win32: falls back to HOME when HOMEDRIVE/HOMEPATH are partial', function (st) {
81+
clearEnv(st);
82+
st.teardown(mockProperty(process, 'platform', { value: 'win32' }));
83+
84+
var homedir = getFallback(st);
85+
86+
st.teardown(mockProperty(process.env, 'HOME', { value: 'C:\\Users\\baz' }));
87+
st.teardown(mockProperty(process.env, 'HOMEDRIVE', { value: 'C:' }));
88+
89+
st.equal(homedir(), 'C:\\Users\\baz', 'falls back to HOME');
90+
91+
st.end();
92+
});
93+
94+
t.end();
95+
});

0 commit comments

Comments
 (0)