Skip to content

Commit 4934b0f

Browse files
crishojnicolas-grekas
authored andcommitted
[Filesystem] Handle paths on different drives
1 parent 78a93e5 commit 4934b0f

File tree

2 files changed

+21
-18
lines changed

2 files changed

+21
-18
lines changed

Diff for: Filesystem.php

+17-18
Original file line numberDiff line numberDiff line change
@@ -455,37 +455,36 @@ public function makePathRelative($endPath, $startPath)
455455
$startPath = str_replace('\\', '/', $startPath);
456456
}
457457

458-
$stripDriveLetter = function ($path) {
459-
if (\strlen($path) > 2 && ':' === $path[1] && '/' === $path[2] && ctype_alpha($path[0])) {
460-
return substr($path, 2);
461-
}
462-
463-
return $path;
458+
$splitDriveLetter = function ($path) {
459+
return (\strlen($path) > 2 && ':' === $path[1] && '/' === $path[2] && ctype_alpha($path[0]))
460+
? [substr($path, 2), strtoupper($path[0])]
461+
: [$path, null];
464462
};
465463

466-
$endPath = $stripDriveLetter($endPath);
467-
$startPath = $stripDriveLetter($startPath);
468-
469-
// Split the paths into arrays
470-
$startPathArr = explode('/', trim($startPath, '/'));
471-
$endPathArr = explode('/', trim($endPath, '/'));
472-
473-
$normalizePathArray = function ($pathSegments, $absolute) {
464+
$splitPath = function ($path, $absolute) {
474465
$result = [];
475466

476-
foreach ($pathSegments as $segment) {
467+
foreach (explode('/', trim($path, '/')) as $segment) {
477468
if ('..' === $segment && ($absolute || \count($result))) {
478469
array_pop($result);
479-
} elseif ('.' !== $segment) {
470+
} elseif ('.' !== $segment && '' !== $segment) {
480471
$result[] = $segment;
481472
}
482473
}
483474

484475
return $result;
485476
};
486477

487-
$startPathArr = $normalizePathArray($startPathArr, static::isAbsolutePath($startPath));
488-
$endPathArr = $normalizePathArray($endPathArr, static::isAbsolutePath($endPath));
478+
list($endPath, $endDriveLetter) = $splitDriveLetter($endPath);
479+
list($startPath, $startDriveLetter) = $splitDriveLetter($startPath);
480+
481+
$startPathArr = $splitPath($startPath, static::isAbsolutePath($startPath));
482+
$endPathArr = $splitPath($endPath, static::isAbsolutePath($endPath));
483+
484+
if ($endDriveLetter && $startDriveLetter && $endDriveLetter != $startDriveLetter) {
485+
// End path is on another drive, so no relative path exists
486+
return $endDriveLetter.':/'.($endPathArr ? implode('/', $endPathArr).'/' : '');
487+
}
489488

490489
// Find for which directory the common path stops
491490
$index = 0;

Diff for: Tests/FilesystemTest.php

+4
Original file line numberDiff line numberDiff line change
@@ -1111,10 +1111,14 @@ public function providePathsForMakePathRelative()
11111111
['/../aa/bb/cc', '/aa/dd/..', 'bb/cc/'],
11121112
['/../../aa/../bb/cc', '/aa/dd/..', '../bb/cc/'],
11131113
['C:/aa/bb/cc', 'C:/aa/dd/..', 'bb/cc/'],
1114+
['C:/aa/bb/cc', 'c:/aa/dd/..', 'bb/cc/'],
11141115
['c:/aa/../bb/cc', 'c:/aa/dd/..', '../bb/cc/'],
11151116
['C:/aa/bb/../../cc', 'C:/aa/../dd/..', 'cc/'],
11161117
['C:/../aa/bb/cc', 'C:/aa/dd/..', 'bb/cc/'],
11171118
['C:/../../aa/../bb/cc', 'C:/aa/dd/..', '../bb/cc/'],
1119+
['D:/', 'C:/aa/../bb/cc', 'D:/'],
1120+
['D:/aa/bb', 'C:/aa', 'D:/aa/bb/'],
1121+
['D:/../../aa/../bb/cc', 'C:/aa/dd/..', 'D:/bb/cc/'],
11181122
];
11191123

11201124
if ('\\' === \DIRECTORY_SEPARATOR) {

0 commit comments

Comments
 (0)