path: fix relative on Windows

PR-URL: https://github.com/nodejs/node/pull/53991
Fixes: https://github.com/nodejs/node/issues/27534
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
Hüseyin Açacak 2024-08-06 12:40:23 +03:00 committed by GitHub
parent 5bfebfec88
commit c852e222cb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 46 additions and 0 deletions

View File

@ -9,6 +9,7 @@ const bench = common.createBenchmark(main, {
['C:\\foo\\bar\\baz', 'C:\\foo\\bar\\baz'].join('|'),
['C:\\foo\\BAR\\BAZ', 'C:\\foo\\bar\\baz'].join('|'),
['C:\\foo\\bar\\baz\\quux', 'C:\\'].join('|'),
['c:\\İ\\a\\İ', 'c:\\İ\\b\\İ\\test.txt', '..\\..\\b\\İ\\test.txt'].join('|'),
],
n: [1e5],
});

View File

@ -22,12 +22,16 @@
'use strict';
const {
ArrayPrototypeJoin,
ArrayPrototypeSlice,
FunctionPrototypeBind,
StringPrototypeCharCodeAt,
StringPrototypeIndexOf,
StringPrototypeLastIndexOf,
StringPrototypeRepeat,
StringPrototypeReplace,
StringPrototypeSlice,
StringPrototypeSplit,
StringPrototypeToLowerCase,
} = primordials;
@ -539,6 +543,42 @@ const win32 = {
if (from === to)
return '';
if (fromOrig.length !== from.length || toOrig.length !== to.length) {
const fromSplit = StringPrototypeSplit(fromOrig, '\\');
const toSplit = StringPrototypeSplit(toOrig, '\\');
if (fromSplit[fromSplit.length - 1] === '') {
fromSplit.pop();
}
if (toSplit[toSplit.length - 1] === '') {
toSplit.pop();
}
const fromLen = fromSplit.length;
const toLen = toSplit.length;
const length = fromLen < toLen ? fromLen : toLen;
let i;
for (i = 0; i < length; i++) {
if (StringPrototypeToLowerCase(fromSplit[i]) !== StringPrototypeToLowerCase(toSplit[i])) {
break;
}
}
if (i === 0) {
return toOrig;
} else if (i === length) {
if (toLen > length) {
return ArrayPrototypeJoin(ArrayPrototypeSlice(toSplit, i), '\\');
}
if (fromLen > length) {
return StringPrototypeRepeat('..\\', fromLen - 1 - i) + '..';
}
return '';
}
return StringPrototypeRepeat('..\\', fromLen - i) + ArrayPrototypeJoin(ArrayPrototypeSlice(toSplit, i), '\\');
}
// Trim any leading backslashes
let fromStart = 0;
while (fromStart < from.length &&

View File

@ -32,6 +32,11 @@ const relativeTests = [
['\\\\foo\\baz', '\\\\foo\\baz-quux', '..\\baz-quux'],
['C:\\baz', '\\\\foo\\bar\\baz', '\\\\foo\\bar\\baz'],
['\\\\foo\\bar\\baz', 'C:\\baz', 'C:\\baz'],
['c:\\a\\İ', 'c:\\a\\İ\\test.txt', 'test.txt'],
['c:\\İ\\a\\İ', 'c:\\İ\\b\\İ\\test.txt', '..\\..\\b\\İ\\test.txt'],
['c:\\İ\\a\\i̇', 'c:\\İ\\b\\İ\\test.txt', '..\\..\\b\\İ\\test.txt'],
['c:\\i̇\\a\\İ', 'c:\\İ\\b\\İ\\test.txt', '..\\..\\b\\İ\\test.txt'],
['c:\\ß\\a\\ß', 'c:\\ß\\b\\ß\\test.txt', '..\\..\\b\\ß\\test.txt'],
],
],
[ path.posix.relative,