diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index 3a5e332b9ece..edfc1b9d46a2 100644 --- a/src/Symfony/Component/Filesystem/Filesystem.php +++ b/src/Symfony/Component/Filesystem/Filesystem.php @@ -362,6 +362,31 @@ public function makePathRelative($endPath, $startPath) $startPathArr = explode('/', trim($startPath, '/')); $endPathArr = explode('/', trim($endPath, '/')); + if ('/' !== $startPath[0]) { + array_shift($startPathArr); + } + + if ('/' !== $endPath[0]) { + array_shift($endPathArr); + } + + $normalizePathArray = function ($pathSegments) { + $result = array(); + + foreach ($pathSegments as $segment) { + if ('..' === $segment) { + array_pop($result); + } else { + $result[] = $segment; + } + } + + return $result; + }; + + $startPathArr = $normalizePathArray($startPathArr); + $endPathArr = $normalizePathArray($endPathArr); + // Find for which directory the common path stops $index = 0; while (isset($startPathArr[$index]) && isset($endPathArr[$index]) && $startPathArr[$index] === $endPathArr[$index]) { diff --git a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php index be47a2d0ce72..ab2395cd001c 100644 --- a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php +++ b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php @@ -868,6 +868,16 @@ public function providePathsForMakePathRelative() array('/a/aab/bb/', '/b/aab', '../../a/aab/bb/'), array('/aab/bb', '/aa', '../aab/bb/'), array('/aab', '/aa', '../aab/'), + array('/aa/bb/cc', '/aa/dd/..', 'bb/cc/'), + array('/aa/../bb/cc', '/aa/dd/..', '../bb/cc/'), + array('/aa/bb/../../cc', '/aa/../dd/..', 'cc/'), + array('/../aa/bb/cc', '/aa/dd/..', 'bb/cc/'), + array('/../../aa/../bb/cc', '/aa/dd/..', '../bb/cc/'), + array('C:/aa/bb/cc', 'C:/aa/dd/..', 'bb/cc/'), + array('c:/aa/../bb/cc', 'c:/aa/dd/..', '../bb/cc/'), + array('C:/aa/bb/../../cc', 'C:/aa/../dd/..', 'cc/'), + array('C:/../aa/bb/cc', 'C:/aa/dd/..', 'bb/cc/'), + array('C:/../../aa/../bb/cc', 'C:/aa/dd/..', '../bb/cc/'), ); if ('\\' === DIRECTORY_SEPARATOR) {