Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 6def8d1

Browse filesBrowse files
committed
Refactored Filesystem::makePathRelative function to correctly handle more use-cases
1 parent 064ad62 commit 6def8d1
Copy full SHA for 6def8d1

File tree

2 files changed

+30
-7
lines changed
Filter options

2 files changed

+30
-7
lines changed

‎src/Symfony/Component/Filesystem/Filesystem.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Filesystem/Filesystem.php
+14-7Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -302,21 +302,28 @@ public function makePathRelative($endPath, $startPath)
302302
$startPath = strtr($startPath, '\\', '/');
303303
}
304304

305-
// Find for which character the the common path stops
306-
$offset = 0;
307-
while (isset($startPath[$offset]) && isset($endPath[$offset]) && $startPath[$offset] === $endPath[$offset]) {
308-
$offset++;
305+
// Split the paths into arrays
306+
$startPathArr = explode('/', trim($startPath, '/'));
307+
$endPathArr = explode('/', trim($endPath, '/'));
308+
309+
// Find for which directory the common path stops
310+
$index = 0;
311+
while (isset($startPathArr[$index]) && isset($endPathArr[$index]) && $startPathArr[$index] === $endPathArr[$index]) {
312+
$index++;
309313
}
310314

311315
// Determine how deep the start path is relative to the common path (ie, "web/bundles" = 2 levels)
312-
$diffPath = trim(substr($startPath, $offset), '/');
313-
$depth = strlen($diffPath) > 0 ? substr_count($diffPath, '/') + 1 : 0;
316+
$depth = count($startPathArr) - $index;
314317

315318
// Repeated "../" for each level need to reach the common path
316319
$traverser = str_repeat('../', $depth);
317320

321+
$endPathRemainder = implode('/', array_slice($endPathArr, $index));
322+
318323
// Construct $endPath from traversing to the common path, then to the remaining $endPath
319-
return $traverser.substr($endPath, $offset);
324+
$relativePath = $traverser . (strlen($endPathRemainder) > 0 ? $endPathRemainder . '/' : '');
325+
326+
return (strlen($relativePath) === 0) ? './' : $relativePath;
320327
}
321328

322329
/**

‎src/Symfony/Component/Filesystem/Tests/FilesystemTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Filesystem/Tests/FilesystemTest.php
+16Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,22 @@ public function providePathsForMakePathRelative()
733733
array('var/lib/symfony/', 'var/lib/symfony/src/Symfony/Component', '../../../'),
734734
array('/usr/lib/symfony/', '/var/lib/symfony/src/Symfony/Component', '../../../../../../usr/lib/symfony/'),
735735
array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/', 'src/Symfony/'),
736+
array('/aa/bb', '/aa/bb', './'),
737+
array('/aa/bb', '/aa/bb/', './'),
738+
array('/aa/bb/', '/aa/bb', './'),
739+
array('/aa/bb/', '/aa/bb/', './'),
740+
array('/aa/bb/cc', '/aa/bb/cc/dd', '../'),
741+
array('/aa/bb/cc', '/aa/bb/cc/dd/', '../'),
742+
array('/aa/bb/cc/', '/aa/bb/cc/dd', '../'),
743+
array('/aa/bb/cc/', '/aa/bb/cc/dd/', '../'),
744+
array('/aa/bb/cc', '/aa', 'bb/cc/'),
745+
array('/aa/bb/cc', '/aa/', 'bb/cc/'),
746+
array('/aa/bb/cc/', '/aa', 'bb/cc/'),
747+
array('/aa/bb/cc/', '/aa/', 'bb/cc/'),
748+
array('/a/aab/bb', '/a/aa', '../aab/bb/'),
749+
array('/a/aab/bb', '/a/aa/', '../aab/bb/'),
750+
array('/a/aab/bb/', '/a/aa', '../aab/bb/'),
751+
array('/a/aab/bb/', '/a/aa/', '../aab/bb/'),
736752
);
737753

738754
if (defined('PHP_WINDOWS_VERSION_MAJOR')) {

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.