Skip to content

Commit f9d0016

Browse files
targosMylesBorins
authored andcommitted
path: fix normalize on directories with two dots
PR-URL: #14107 Fixes: #14105 Reviewed-By: Refael Ackermann <[email protected]>
1 parent f6b4063 commit f9d0016

File tree

2 files changed

+22
-2
lines changed

2 files changed

+22
-2
lines changed

lib/path.js

+12-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ function normalizeStringWin32(path, allowAboveRoot) {
1414
var lastSlash = -1;
1515
var dots = 0;
1616
var code;
17+
var isAboveRoot = false;
1718
for (var i = 0; i <= path.length; ++i) {
1819
if (i < path.length)
1920
code = path.charCodeAt(i);
@@ -25,7 +26,7 @@ function normalizeStringWin32(path, allowAboveRoot) {
2526
if (lastSlash === i - 1 || dots === 1) {
2627
// NOOP
2728
} else if (lastSlash !== i - 1 && dots === 2) {
28-
if (res.length < 2 ||
29+
if (res.length < 2 || !isAboveRoot ||
2930
res.charCodeAt(res.length - 1) !== 46/*.*/ ||
3031
res.charCodeAt(res.length - 2) !== 46/*.*/) {
3132
if (res.length > 2) {
@@ -42,12 +43,14 @@ function normalizeStringWin32(path, allowAboveRoot) {
4243
res = res.slice(0, j);
4344
lastSlash = i;
4445
dots = 0;
46+
isAboveRoot = false;
4547
continue;
4648
}
4749
} else if (res.length === 2 || res.length === 1) {
4850
res = '';
4951
lastSlash = i;
5052
dots = 0;
53+
isAboveRoot = false;
5154
continue;
5255
}
5356
}
@@ -56,12 +59,14 @@ function normalizeStringWin32(path, allowAboveRoot) {
5659
res += '\\..';
5760
else
5861
res = '..';
62+
isAboveRoot = true;
5963
}
6064
} else {
6165
if (res.length > 0)
6266
res += '\\' + path.slice(lastSlash + 1, i);
6367
else
6468
res = path.slice(lastSlash + 1, i);
69+
isAboveRoot = false;
6570
}
6671
lastSlash = i;
6772
dots = 0;
@@ -80,6 +85,7 @@ function normalizeStringPosix(path, allowAboveRoot) {
8085
var lastSlash = -1;
8186
var dots = 0;
8287
var code;
88+
var isAboveRoot = false;
8389
for (var i = 0; i <= path.length; ++i) {
8490
if (i < path.length)
8591
code = path.charCodeAt(i);
@@ -91,7 +97,7 @@ function normalizeStringPosix(path, allowAboveRoot) {
9197
if (lastSlash === i - 1 || dots === 1) {
9298
// NOOP
9399
} else if (lastSlash !== i - 1 && dots === 2) {
94-
if (res.length < 2 ||
100+
if (res.length < 2 || !isAboveRoot ||
95101
res.charCodeAt(res.length - 1) !== 46/*.*/ ||
96102
res.charCodeAt(res.length - 2) !== 46/*.*/) {
97103
if (res.length > 2) {
@@ -108,12 +114,14 @@ function normalizeStringPosix(path, allowAboveRoot) {
108114
res = res.slice(0, j);
109115
lastSlash = i;
110116
dots = 0;
117+
isAboveRoot = false;
111118
continue;
112119
}
113120
} else if (res.length === 2 || res.length === 1) {
114121
res = '';
115122
lastSlash = i;
116123
dots = 0;
124+
isAboveRoot = false;
117125
continue;
118126
}
119127
}
@@ -122,12 +130,14 @@ function normalizeStringPosix(path, allowAboveRoot) {
122130
res += '/..';
123131
else
124132
res = '..';
133+
isAboveRoot = true;
125134
}
126135
} else {
127136
if (res.length > 0)
128137
res += '/' + path.slice(lastSlash + 1, i);
129138
else
130139
res = path.slice(lastSlash + 1, i);
140+
isAboveRoot = false;
131141
}
132142
lastSlash = i;
133143
dots = 0;

test/parallel/test-path.js

+10
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,11 @@ assert.strictEqual(path.win32.normalize('C:..\\..\\abc\\..\\def'),
411411
'C:..\\..\\def');
412412
assert.strictEqual(path.win32.normalize('C:\\.'), 'C:\\');
413413
assert.strictEqual(path.win32.normalize('file:stream'), 'file:stream');
414+
assert.strictEqual(path.win32.normalize('bar\\foo..\\..\\'), 'bar\\');
415+
assert.strictEqual(path.win32.normalize('bar\\foo..\\..'), 'bar');
416+
assert.strictEqual(path.win32.normalize('bar\\foo..\\..\\baz'), 'bar\\baz');
417+
assert.strictEqual(path.win32.normalize('bar\\foo..\\'), 'bar\\foo..\\');
418+
assert.strictEqual(path.win32.normalize('bar\\foo..'), 'bar\\foo..');
414419

415420
assert.strictEqual(path.posix.normalize('./fixtures///b/../b/c.js'),
416421
'fixtures/b/c.js');
@@ -420,6 +425,11 @@ assert.strictEqual(path.posix.normalize('a//b//./c'), 'a/b/c');
420425
assert.strictEqual(path.posix.normalize('a//b//.'), 'a/b');
421426
assert.strictEqual(path.posix.normalize('/a/b/c/../../../x/y/z'), '/x/y/z');
422427
assert.strictEqual(path.posix.normalize('///..//./foo/.//bar'), '/foo/bar');
428+
assert.strictEqual(path.posix.normalize('bar/foo../../'), 'bar/');
429+
assert.strictEqual(path.posix.normalize('bar/foo../..'), 'bar');
430+
assert.strictEqual(path.posix.normalize('bar/foo../../baz'), 'bar/baz');
431+
assert.strictEqual(path.posix.normalize('bar/foo../'), 'bar/foo../');
432+
assert.strictEqual(path.posix.normalize('bar/foo..'), 'bar/foo..');
423433

424434

425435
// path.resolve tests

0 commit comments

Comments
 (0)