diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index 1b6721bec422f..8bf81c9da4a7a 100644 --- a/src/Symfony/Component/Filesystem/Filesystem.php +++ b/src/Symfony/Component/Filesystem/Filesystem.php @@ -302,21 +302,28 @@ public function makePathRelative($endPath, $startPath) $startPath = strtr($startPath, '\\', '/'); } - // Find for which character the the common path stops - $offset = 0; - while (isset($startPath[$offset]) && isset($endPath[$offset]) && $startPath[$offset] === $endPath[$offset]) { - $offset++; + // Split the paths into arrays + $startPathArr = explode('/', trim($startPath, '/')); + $endPathArr = explode('/', trim($endPath, '/')); + + // Find for which directory the common path stops + $index = 0; + while (isset($startPathArr[$index]) && isset($endPathArr[$index]) && $startPathArr[$index] === $endPathArr[$index]) { + $index++; } // Determine how deep the start path is relative to the common path (ie, "web/bundles" = 2 levels) - $diffPath = trim(substr($startPath, $offset), '/'); - $depth = strlen($diffPath) > 0 ? substr_count($diffPath, '/') + 1 : 0; + $depth = count($startPathArr) - $index; // Repeated "../" for each level need to reach the common path $traverser = str_repeat('../', $depth); + $endPathRemainder = implode('/', array_slice($endPathArr, $index)); + // Construct $endPath from traversing to the common path, then to the remaining $endPath - return $traverser.substr($endPath, $offset); + $relativePath = $traverser . (strlen($endPathRemainder) > 0 ? $endPathRemainder . '/' : ''); + + return (strlen($relativePath) === 0) ? './' : $relativePath; } /** diff --git a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php index a29155c4bd7ea..3a935e1885a62 100644 --- a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php +++ b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php @@ -733,6 +733,22 @@ public function providePathsForMakePathRelative() array('var/lib/symfony/', 'var/lib/symfony/src/Symfony/Component', '../../../'), array('/usr/lib/symfony/', '/var/lib/symfony/src/Symfony/Component', '../../../../../../usr/lib/symfony/'), array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/', 'src/Symfony/'), + array('/aa/bb', '/aa/bb', './'), + array('/aa/bb', '/aa/bb/', './'), + array('/aa/bb/', '/aa/bb', './'), + array('/aa/bb/', '/aa/bb/', './'), + array('/aa/bb/cc', '/aa/bb/cc/dd', '../'), + array('/aa/bb/cc', '/aa/bb/cc/dd/', '../'), + array('/aa/bb/cc/', '/aa/bb/cc/dd', '../'), + array('/aa/bb/cc/', '/aa/bb/cc/dd/', '../'), + array('/aa/bb/cc', '/aa', 'bb/cc/'), + array('/aa/bb/cc', '/aa/', 'bb/cc/'), + array('/aa/bb/cc/', '/aa', 'bb/cc/'), + array('/aa/bb/cc/', '/aa/', 'bb/cc/'), + array('/a/aab/bb', '/a/aa', '../aab/bb/'), + array('/a/aab/bb', '/a/aa/', '../aab/bb/'), + array('/a/aab/bb/', '/a/aa', '../aab/bb/'), + array('/a/aab/bb/', '/a/aa/', '../aab/bb/'), ); if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
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: