Skip to content

Commit c61cee2

Browse files
huseyinacacak-janeatargos
authored andcommittedOct 2, 2024
path: fix relative on Windows
PR-URL: #53991 Fixes: #27534 Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 56cbc80 commit c61cee2

File tree

3 files changed

+46
-0
lines changed

3 files changed

+46
-0
lines changed
 

‎benchmark/path/relative-win32.js

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const bench = common.createBenchmark(main, {
99
['C:\\foo\\bar\\baz', 'C:\\foo\\bar\\baz'].join('|'),
1010
['C:\\foo\\BAR\\BAZ', 'C:\\foo\\bar\\baz'].join('|'),
1111
['C:\\foo\\bar\\baz\\quux', 'C:\\'].join('|'),
12+
['c:\\İ\\a\\İ', 'c:\\İ\\b\\İ\\test.txt', '..\\..\\b\\İ\\test.txt'].join('|'),
1213
],
1314
n: [1e5],
1415
});

‎lib/path.js

+40
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,16 @@
2222
'use strict';
2323

2424
const {
25+
ArrayPrototypeJoin,
26+
ArrayPrototypeSlice,
2527
FunctionPrototypeBind,
2628
StringPrototypeCharCodeAt,
2729
StringPrototypeIndexOf,
2830
StringPrototypeLastIndexOf,
31+
StringPrototypeRepeat,
2932
StringPrototypeReplace,
3033
StringPrototypeSlice,
34+
StringPrototypeSplit,
3135
StringPrototypeToLowerCase,
3236
} = primordials;
3337

@@ -540,6 +544,42 @@ const win32 = {
540544
if (from === to)
541545
return '';
542546

547+
if (fromOrig.length !== from.length || toOrig.length !== to.length) {
548+
const fromSplit = StringPrototypeSplit(fromOrig, '\\');
549+
const toSplit = StringPrototypeSplit(toOrig, '\\');
550+
if (fromSplit[fromSplit.length - 1] === '') {
551+
fromSplit.pop();
552+
}
553+
if (toSplit[toSplit.length - 1] === '') {
554+
toSplit.pop();
555+
}
556+
557+
const fromLen = fromSplit.length;
558+
const toLen = toSplit.length;
559+
const length = fromLen < toLen ? fromLen : toLen;
560+
561+
let i;
562+
for (i = 0; i < length; i++) {
563+
if (StringPrototypeToLowerCase(fromSplit[i]) !== StringPrototypeToLowerCase(toSplit[i])) {
564+
break;
565+
}
566+
}
567+
568+
if (i === 0) {
569+
return toOrig;
570+
} else if (i === length) {
571+
if (toLen > length) {
572+
return ArrayPrototypeJoin(ArrayPrototypeSlice(toSplit, i), '\\');
573+
}
574+
if (fromLen > length) {
575+
return StringPrototypeRepeat('..\\', fromLen - 1 - i) + '..';
576+
}
577+
return '';
578+
}
579+
580+
return StringPrototypeRepeat('..\\', fromLen - i) + ArrayPrototypeJoin(ArrayPrototypeSlice(toSplit, i), '\\');
581+
}
582+
543583
// Trim any leading backslashes
544584
let fromStart = 0;
545585
while (fromStart < from.length &&

‎test/parallel/test-path-relative.js

+5
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ const relativeTests = [
3232
['\\\\foo\\baz', '\\\\foo\\baz-quux', '..\\baz-quux'],
3333
['C:\\baz', '\\\\foo\\bar\\baz', '\\\\foo\\bar\\baz'],
3434
['\\\\foo\\bar\\baz', 'C:\\baz', 'C:\\baz'],
35+
['c:\\a\\İ', 'c:\\a\\İ\\test.txt', 'test.txt'],
36+
['c:\\İ\\a\\İ', 'c:\\İ\\b\\İ\\test.txt', '..\\..\\b\\İ\\test.txt'],
37+
['c:\\İ\\a\\i̇', 'c:\\İ\\b\\İ\\test.txt', '..\\..\\b\\İ\\test.txt'],
38+
['c:\\i̇\\a\\İ', 'c:\\İ\\b\\İ\\test.txt', '..\\..\\b\\İ\\test.txt'],
39+
['c:\\ß\\a\\ß', 'c:\\ß\\b\\ß\\test.txt', '..\\..\\b\\ß\\test.txt'],
3540
],
3641
],
3742
[ path.posix.relative,

0 commit comments

Comments
 (0)
Please sign in to comment.