path: fix normalize paths ending with two dots
Fixes: https://github.com/nodejs/security/issues/147 PR-URL: https://github.com/nodejs-private/node-private/pull/94 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Doug Wilson <doug@somethingdoug.com> Reviewed-By: Myles Borins <myles.borins@gmail.com> Reviewed-By: Evan Lucas <evanlucas@me.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
This commit is contained in:
parent
05e4c1d6bc
commit
cfee1c9778
36
lib/path.js
36
lib/path.js
@ -32,10 +32,10 @@ function assertPath(path) {
|
||||
// Resolves . and .. elements in a path with directory names
|
||||
function normalizeStringWin32(path, allowAboveRoot) {
|
||||
var res = '';
|
||||
var lastSegmentLength = 0;
|
||||
var lastSlash = -1;
|
||||
var dots = 0;
|
||||
var code;
|
||||
var isAboveRoot = false;
|
||||
for (var i = 0; i <= path.length; ++i) {
|
||||
if (i < path.length)
|
||||
code = path.charCodeAt(i);
|
||||
@ -47,7 +47,7 @@ function normalizeStringWin32(path, allowAboveRoot) {
|
||||
if (lastSlash === i - 1 || dots === 1) {
|
||||
// NOOP
|
||||
} else if (lastSlash !== i - 1 && dots === 2) {
|
||||
if (res.length < 2 || !isAboveRoot ||
|
||||
if (res.length < 2 || lastSegmentLength !== 2 ||
|
||||
res.charCodeAt(res.length - 1) !== 46/*.*/ ||
|
||||
res.charCodeAt(res.length - 2) !== 46/*.*/) {
|
||||
if (res.length > 2) {
|
||||
@ -58,20 +58,22 @@ function normalizeStringWin32(path, allowAboveRoot) {
|
||||
break;
|
||||
}
|
||||
if (j !== start) {
|
||||
if (j === -1)
|
||||
if (j === -1) {
|
||||
res = '';
|
||||
else
|
||||
lastSegmentLength = 0;
|
||||
} else {
|
||||
res = res.slice(0, j);
|
||||
lastSegmentLength = j;
|
||||
}
|
||||
lastSlash = i;
|
||||
dots = 0;
|
||||
isAboveRoot = false;
|
||||
continue;
|
||||
}
|
||||
} else if (res.length === 2 || res.length === 1) {
|
||||
res = '';
|
||||
lastSegmentLength = 0;
|
||||
lastSlash = i;
|
||||
dots = 0;
|
||||
isAboveRoot = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -80,14 +82,14 @@ function normalizeStringWin32(path, allowAboveRoot) {
|
||||
res += '\\..';
|
||||
else
|
||||
res = '..';
|
||||
isAboveRoot = true;
|
||||
lastSegmentLength = 2;
|
||||
}
|
||||
} else {
|
||||
if (res.length > 0)
|
||||
res += '\\' + path.slice(lastSlash + 1, i);
|
||||
else
|
||||
res = path.slice(lastSlash + 1, i);
|
||||
isAboveRoot = false;
|
||||
lastSegmentLength = i - lastSlash - 1;
|
||||
}
|
||||
lastSlash = i;
|
||||
dots = 0;
|
||||
@ -103,10 +105,10 @@ function normalizeStringWin32(path, allowAboveRoot) {
|
||||
// Resolves . and .. elements in a path with directory names
|
||||
function normalizeStringPosix(path, allowAboveRoot) {
|
||||
var res = '';
|
||||
var lastSegmentLength = 0;
|
||||
var lastSlash = -1;
|
||||
var dots = 0;
|
||||
var code;
|
||||
var isAboveRoot = false;
|
||||
for (var i = 0; i <= path.length; ++i) {
|
||||
if (i < path.length)
|
||||
code = path.charCodeAt(i);
|
||||
@ -118,7 +120,7 @@ function normalizeStringPosix(path, allowAboveRoot) {
|
||||
if (lastSlash === i - 1 || dots === 1) {
|
||||
// NOOP
|
||||
} else if (lastSlash !== i - 1 && dots === 2) {
|
||||
if (res.length < 2 || !isAboveRoot ||
|
||||
if (res.length < 2 || lastSegmentLength !== 2 ||
|
||||
res.charCodeAt(res.length - 1) !== 46/*.*/ ||
|
||||
res.charCodeAt(res.length - 2) !== 46/*.*/) {
|
||||
if (res.length > 2) {
|
||||
@ -129,20 +131,22 @@ function normalizeStringPosix(path, allowAboveRoot) {
|
||||
break;
|
||||
}
|
||||
if (j !== start) {
|
||||
if (j === -1)
|
||||
if (j === -1) {
|
||||
res = '';
|
||||
else
|
||||
lastSegmentLength = 0;
|
||||
} else {
|
||||
res = res.slice(0, j);
|
||||
lastSegmentLength = j;
|
||||
}
|
||||
lastSlash = i;
|
||||
dots = 0;
|
||||
isAboveRoot = false;
|
||||
continue;
|
||||
}
|
||||
} else if (res.length === 2 || res.length === 1) {
|
||||
res = '';
|
||||
lastSegmentLength = 0;
|
||||
lastSlash = i;
|
||||
dots = 0;
|
||||
isAboveRoot = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -151,14 +155,14 @@ function normalizeStringPosix(path, allowAboveRoot) {
|
||||
res += '/..';
|
||||
else
|
||||
res = '..';
|
||||
isAboveRoot = true;
|
||||
lastSegmentLength = 2;
|
||||
}
|
||||
} else {
|
||||
if (res.length > 0)
|
||||
res += '/' + path.slice(lastSlash + 1, i);
|
||||
else
|
||||
res = path.slice(lastSlash + 1, i);
|
||||
isAboveRoot = false;
|
||||
lastSegmentLength = i - lastSlash - 1;
|
||||
}
|
||||
lastSlash = i;
|
||||
dots = 0;
|
||||
|
@ -23,6 +23,10 @@ assert.strictEqual(path.win32.normalize('bar\\foo..\\..'), 'bar');
|
||||
assert.strictEqual(path.win32.normalize('bar\\foo..\\..\\baz'), 'bar\\baz');
|
||||
assert.strictEqual(path.win32.normalize('bar\\foo..\\'), 'bar\\foo..\\');
|
||||
assert.strictEqual(path.win32.normalize('bar\\foo..'), 'bar\\foo..');
|
||||
assert.strictEqual(path.win32.normalize('..\\foo..\\..\\..\\bar'),
|
||||
'..\\..\\bar');
|
||||
assert.strictEqual(path.win32.normalize('..\\...\\..\\.\\...\\..\\..\\bar'),
|
||||
'..\\..\\bar');
|
||||
|
||||
assert.strictEqual(path.posix.normalize('./fixtures///b/../b/c.js'),
|
||||
'fixtures/b/c.js');
|
||||
@ -37,3 +41,6 @@ assert.strictEqual(path.posix.normalize('bar/foo../..'), 'bar');
|
||||
assert.strictEqual(path.posix.normalize('bar/foo../../baz'), 'bar/baz');
|
||||
assert.strictEqual(path.posix.normalize('bar/foo../'), 'bar/foo../');
|
||||
assert.strictEqual(path.posix.normalize('bar/foo..'), 'bar/foo..');
|
||||
assert.strictEqual(path.posix.normalize('../foo../../../bar'), '../../bar');
|
||||
assert.strictEqual(path.posix.normalize('../.../.././.../../../bar'),
|
||||
'../../bar');
|
||||
|
Loading…
x
Reference in New Issue
Block a user