Skip to content

Commit c61cee2

Browse files
huseyinacacak-janeatargos
authored andcommitted
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 40 additions & 0 deletions
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

Lines changed: 5 additions & 0 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy