Skip to content

Commit b0a4f16

Browse files
committed
path: fix win32 normalize false-positive on reserved names
`path.win32.normalize()` checked for Windows reserved device names (CON, NUL, PRN, LPT1, etc.) without first ensuring the path actually contained a colon. When no colon was present, `indexOf(':')` returned -1 and `isWindowsReservedName()` sliced off the last character instead of slicing up to a colon, so any filename equal to a reserved name plus one trailing character was wrongly treated as a device and prefixed with `.\` — e.g. `normalize('CONx')` returned `.\CONx` instead of `CONx`. Guard the check with `colonIndex !== -1`, matching the other reserved name call sites which are already guarded by `colonIndex > 0`. Signed-off-by: Daijiro Wachi <daijiro.wachi@gmail.com> PR-URL: #64159 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
1 parent d5679f4 commit b0a4f16

2 files changed

Lines changed: 12 additions & 1 deletion

File tree

lib/path.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ const win32 = {
471471
} while ((index = StringPrototypeIndexOf(path, ':', index + 1)) !== -1);
472472
}
473473
const colonIndex = StringPrototypeIndexOf(path, ':');
474-
if (isWindowsReservedName(path, colonIndex)) {
474+
if (colonIndex !== -1 && isWindowsReservedName(path, colonIndex)) {
475475
return `.\\${device ?? ''}${tail}`;
476476
}
477477
if (device === undefined) {

test/parallel/test-path-normalize.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,17 @@ assert.strictEqual(path.win32.normalize('//server/share/dir/../../../?/D:/file')
6969
assert.strictEqual(path.win32.normalize('//server/goodshare/../badshare/file'),
7070
'\\\\server\\goodshare\\badshare\\file');
7171

72+
// A path is only a Windows reserved device name when the reserved name is
73+
// followed by a colon. A name that merely starts with a reserved name (and has
74+
// no colon) must be left untouched and not be prefixed with `.\`.
75+
assert.strictEqual(path.win32.normalize('CONx'), 'CONx');
76+
assert.strictEqual(path.win32.normalize('NULs'), 'NULs');
77+
assert.strictEqual(path.win32.normalize('LPT1x'), 'LPT1x');
78+
assert.strictEqual(path.win32.normalize('PRNzzz'), 'PRNzzz');
79+
assert.strictEqual(path.win32.normalize('CON'), 'CON');
80+
// With a trailing colon the reserved-name handling still applies.
81+
assert.strictEqual(path.win32.normalize('CON:'), '.\\CON:.');
82+
7283
assert.strictEqual(path.posix.normalize('./fixtures///b/../b/c.js'),
7384
'fixtures/b/c.js');
7485
assert.strictEqual(path.posix.normalize('/foo/../../../bar'), '/bar');

0 commit comments

Comments
 (0)