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
|
// Resolves . and .. elements in a path with directory names
|
||||||
function normalizeStringWin32(path, allowAboveRoot) {
|
function normalizeStringWin32(path, allowAboveRoot) {
|
||||||
var res = '';
|
var res = '';
|
||||||
|
var lastSegmentLength = 0;
|
||||||
var lastSlash = -1;
|
var lastSlash = -1;
|
||||||
var dots = 0;
|
var dots = 0;
|
||||||
var code;
|
var code;
|
||||||
var isAboveRoot = false;
|
|
||||||
for (var i = 0; i <= path.length; ++i) {
|
for (var i = 0; i <= path.length; ++i) {
|
||||||
if (i < path.length)
|
if (i < path.length)
|
||||||
code = path.charCodeAt(i);
|
code = path.charCodeAt(i);
|
||||||
@ -47,7 +47,7 @@ function normalizeStringWin32(path, allowAboveRoot) {
|
|||||||
if (lastSlash === i - 1 || dots === 1) {
|
if (lastSlash === i - 1 || dots === 1) {
|
||||||
// NOOP
|
// NOOP
|
||||||
} else if (lastSlash !== i - 1 && dots === 2) {
|
} 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 - 1) !== 46/*.*/ ||
|
||||||
res.charCodeAt(res.length - 2) !== 46/*.*/) {
|
res.charCodeAt(res.length - 2) !== 46/*.*/) {
|
||||||
if (res.length > 2) {
|
if (res.length > 2) {
|
||||||
@ -58,20 +58,22 @@ function normalizeStringWin32(path, allowAboveRoot) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (j !== start) {
|
if (j !== start) {
|
||||||
if (j === -1)
|
if (j === -1) {
|
||||||
res = '';
|
res = '';
|
||||||
else
|
lastSegmentLength = 0;
|
||||||
|
} else {
|
||||||
res = res.slice(0, j);
|
res = res.slice(0, j);
|
||||||
|
lastSegmentLength = j;
|
||||||
|
}
|
||||||
lastSlash = i;
|
lastSlash = i;
|
||||||
dots = 0;
|
dots = 0;
|
||||||
isAboveRoot = false;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else if (res.length === 2 || res.length === 1) {
|
} else if (res.length === 2 || res.length === 1) {
|
||||||
res = '';
|
res = '';
|
||||||
|
lastSegmentLength = 0;
|
||||||
lastSlash = i;
|
lastSlash = i;
|
||||||
dots = 0;
|
dots = 0;
|
||||||
isAboveRoot = false;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,14 +82,14 @@ function normalizeStringWin32(path, allowAboveRoot) {
|
|||||||
res += '\\..';
|
res += '\\..';
|
||||||
else
|
else
|
||||||
res = '..';
|
res = '..';
|
||||||
isAboveRoot = true;
|
lastSegmentLength = 2;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (res.length > 0)
|
if (res.length > 0)
|
||||||
res += '\\' + path.slice(lastSlash + 1, i);
|
res += '\\' + path.slice(lastSlash + 1, i);
|
||||||
else
|
else
|
||||||
res = path.slice(lastSlash + 1, i);
|
res = path.slice(lastSlash + 1, i);
|
||||||
isAboveRoot = false;
|
lastSegmentLength = i - lastSlash - 1;
|
||||||
}
|
}
|
||||||
lastSlash = i;
|
lastSlash = i;
|
||||||
dots = 0;
|
dots = 0;
|
||||||
@ -103,10 +105,10 @@ function normalizeStringWin32(path, allowAboveRoot) {
|
|||||||
// Resolves . and .. elements in a path with directory names
|
// Resolves . and .. elements in a path with directory names
|
||||||
function normalizeStringPosix(path, allowAboveRoot) {
|
function normalizeStringPosix(path, allowAboveRoot) {
|
||||||
var res = '';
|
var res = '';
|
||||||
|
var lastSegmentLength = 0;
|
||||||
var lastSlash = -1;
|
var lastSlash = -1;
|
||||||
var dots = 0;
|
var dots = 0;
|
||||||
var code;
|
var code;
|
||||||
var isAboveRoot = false;
|
|
||||||
for (var i = 0; i <= path.length; ++i) {
|
for (var i = 0; i <= path.length; ++i) {
|
||||||
if (i < path.length)
|
if (i < path.length)
|
||||||
code = path.charCodeAt(i);
|
code = path.charCodeAt(i);
|
||||||
@ -118,7 +120,7 @@ function normalizeStringPosix(path, allowAboveRoot) {
|
|||||||
if (lastSlash === i - 1 || dots === 1) {
|
if (lastSlash === i - 1 || dots === 1) {
|
||||||
// NOOP
|
// NOOP
|
||||||
} else if (lastSlash !== i - 1 && dots === 2) {
|
} 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 - 1) !== 46/*.*/ ||
|
||||||
res.charCodeAt(res.length - 2) !== 46/*.*/) {
|
res.charCodeAt(res.length - 2) !== 46/*.*/) {
|
||||||
if (res.length > 2) {
|
if (res.length > 2) {
|
||||||
@ -129,20 +131,22 @@ function normalizeStringPosix(path, allowAboveRoot) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (j !== start) {
|
if (j !== start) {
|
||||||
if (j === -1)
|
if (j === -1) {
|
||||||
res = '';
|
res = '';
|
||||||
else
|
lastSegmentLength = 0;
|
||||||
|
} else {
|
||||||
res = res.slice(0, j);
|
res = res.slice(0, j);
|
||||||
|
lastSegmentLength = j;
|
||||||
|
}
|
||||||
lastSlash = i;
|
lastSlash = i;
|
||||||
dots = 0;
|
dots = 0;
|
||||||
isAboveRoot = false;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else if (res.length === 2 || res.length === 1) {
|
} else if (res.length === 2 || res.length === 1) {
|
||||||
res = '';
|
res = '';
|
||||||
|
lastSegmentLength = 0;
|
||||||
lastSlash = i;
|
lastSlash = i;
|
||||||
dots = 0;
|
dots = 0;
|
||||||
isAboveRoot = false;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -151,14 +155,14 @@ function normalizeStringPosix(path, allowAboveRoot) {
|
|||||||
res += '/..';
|
res += '/..';
|
||||||
else
|
else
|
||||||
res = '..';
|
res = '..';
|
||||||
isAboveRoot = true;
|
lastSegmentLength = 2;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (res.length > 0)
|
if (res.length > 0)
|
||||||
res += '/' + path.slice(lastSlash + 1, i);
|
res += '/' + path.slice(lastSlash + 1, i);
|
||||||
else
|
else
|
||||||
res = path.slice(lastSlash + 1, i);
|
res = path.slice(lastSlash + 1, i);
|
||||||
isAboveRoot = false;
|
lastSegmentLength = i - lastSlash - 1;
|
||||||
}
|
}
|
||||||
lastSlash = i;
|
lastSlash = i;
|
||||||
dots = 0;
|
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..\\..\\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('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'),
|
assert.strictEqual(path.posix.normalize('./fixtures///b/../b/c.js'),
|
||||||
'fixtures/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../../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('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