diff --git a/Filesystem.php b/Filesystem.php index 47521e71b6..a5539fa5eb 100644 --- a/Filesystem.php +++ b/Filesystem.php @@ -434,28 +434,19 @@ public function makePathRelative(string $endPath, string $startPath) $startPath = str_replace('\\', '/', $startPath); } - $stripDriveLetter = function ($path) { - if (\strlen($path) > 2 && ':' === $path[1] && '/' === $path[2] && ctype_alpha($path[0])) { - return substr($path, 2); - } - - return $path; + $splitDriveLetter = function ($path) { + return (\strlen($path) > 2 && ':' === $path[1] && '/' === $path[2] && ctype_alpha($path[0])) + ? [substr($path, 2), strtoupper($path[0])] + : [$path, null]; }; - $endPath = $stripDriveLetter($endPath); - $startPath = $stripDriveLetter($startPath); - - // Split the paths into arrays - $startPathArr = explode('/', trim($startPath, '/')); - $endPathArr = explode('/', trim($endPath, '/')); - - $normalizePathArray = function ($pathSegments) { + $splitPath = function ($path) { $result = []; - foreach ($pathSegments as $segment) { + foreach (explode('/', trim($path, '/')) as $segment) { if ('..' === $segment) { array_pop($result); - } elseif ('.' !== $segment) { + } elseif ('.' !== $segment && '' !== $segment) { $result[] = $segment; } } @@ -463,8 +454,16 @@ public function makePathRelative(string $endPath, string $startPath) return $result; }; - $startPathArr = $normalizePathArray($startPathArr); - $endPathArr = $normalizePathArray($endPathArr); + list($endPath, $endDriveLetter) = $splitDriveLetter($endPath); + list($startPath, $startDriveLetter) = $splitDriveLetter($startPath); + + $startPathArr = $splitPath($startPath); + $endPathArr = $splitPath($endPath); + + if ($endDriveLetter && $startDriveLetter && $endDriveLetter != $startDriveLetter) { + // End path is on another drive, so no relative path exists + return $endDriveLetter.':/'.($endPathArr ? implode('/', $endPathArr).'/' : ''); + } // Find for which directory the common path stops $index = 0; diff --git a/Tests/FilesystemTest.php b/Tests/FilesystemTest.php index 79b2f61d0c..ab95a429fd 100644 --- a/Tests/FilesystemTest.php +++ b/Tests/FilesystemTest.php @@ -1151,10 +1151,14 @@ public function providePathsForMakePathRelative() ['/../aa/bb/cc', '/aa/dd/..', 'bb/cc/'], ['/../../aa/../bb/cc', '/aa/dd/..', '../bb/cc/'], ['C:/aa/bb/cc', 'C:/aa/dd/..', 'bb/cc/'], + ['C:/aa/bb/cc', 'c:/aa/dd/..', 'bb/cc/'], ['c:/aa/../bb/cc', 'c:/aa/dd/..', '../bb/cc/'], ['C:/aa/bb/../../cc', 'C:/aa/../dd/..', 'cc/'], ['C:/../aa/bb/cc', 'C:/aa/dd/..', 'bb/cc/'], ['C:/../../aa/../bb/cc', 'C:/aa/dd/..', '../bb/cc/'], + ['D:/', 'C:/aa/../bb/cc', 'D:/'], + ['D:/aa/bb', 'C:/aa', 'D:/aa/bb/'], + ['D:/../../aa/../bb/cc', 'C:/aa/dd/..', 'D:/bb/cc/'], ]; if ('\\' === \DIRECTORY_SEPARATOR) {