Fixed behaviour of Filesystem::findShortestPath[Code] for paths with up-level references
parent
e1eb35455f
commit
0851ef1afb
|
@ -202,8 +202,8 @@ class Filesystem
|
||||||
throw new \InvalidArgumentException(sprintf('$from (%s) and $to (%s) must be absolute paths.', $from, $to));
|
throw new \InvalidArgumentException(sprintf('$from (%s) and $to (%s) must be absolute paths.', $from, $to));
|
||||||
}
|
}
|
||||||
|
|
||||||
$from = lcfirst(rtrim(strtr($from, '\\', '/'), '/'));
|
$from = lcfirst($this->normalizePath($from));
|
||||||
$to = lcfirst(rtrim(strtr($to, '\\', '/'), '/'));
|
$to = lcfirst($this->normalizePath($to));
|
||||||
|
|
||||||
if ($directories) {
|
if ($directories) {
|
||||||
$from .= '/dummy_file';
|
$from .= '/dummy_file';
|
||||||
|
@ -243,8 +243,8 @@ class Filesystem
|
||||||
throw new \InvalidArgumentException(sprintf('$from (%s) and $to (%s) must be absolute paths.', $from, $to));
|
throw new \InvalidArgumentException(sprintf('$from (%s) and $to (%s) must be absolute paths.', $from, $to));
|
||||||
}
|
}
|
||||||
|
|
||||||
$from = lcfirst(strtr($from, '\\', '/'));
|
$from = lcfirst($this->normalizePath($from));
|
||||||
$to = lcfirst(strtr($to, '\\', '/'));
|
$to = lcfirst($this->normalizePath($to));
|
||||||
|
|
||||||
if ($from === $to) {
|
if ($from === $to) {
|
||||||
return $directories ? '__DIR__' : '__FILE__';
|
return $directories ? '__DIR__' : '__FILE__';
|
||||||
|
@ -300,6 +300,35 @@ class Filesystem
|
||||||
return filesize($path);
|
return filesize($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize a path. This replaces backslashes with slashes, removes ending
|
||||||
|
* slash and collapses redundant separators and up-level references.
|
||||||
|
*
|
||||||
|
* @param string $path Path to the file or directory
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function normalizePath($path)
|
||||||
|
{
|
||||||
|
$parts = array();
|
||||||
|
$path = strtr($path, '\\', '/');
|
||||||
|
$prefix = '';
|
||||||
|
|
||||||
|
if (preg_match('|^(([a-z]:)?/)|i', $path, $match)) {
|
||||||
|
$prefix = $match[1];
|
||||||
|
$path = substr($path, strlen($prefix));
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (explode('/', $path) as $chunk) {
|
||||||
|
if ('..' === $chunk) {
|
||||||
|
array_pop($parts);
|
||||||
|
} elseif ('.' !== $chunk && '' !== $chunk) {
|
||||||
|
$parts[] = $chunk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $prefix.implode('/', $parts);
|
||||||
|
}
|
||||||
|
|
||||||
protected function directorySize($directory)
|
protected function directorySize($directory)
|
||||||
{
|
{
|
||||||
$it = new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS);
|
$it = new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS);
|
||||||
|
|
|
@ -38,6 +38,7 @@ class FilesystemTest extends TestCase
|
||||||
array('c:/bin/run', 'd:/vendor/acme/bin/run', false, "'d:/vendor/acme/bin/run'"),
|
array('c:/bin/run', 'd:/vendor/acme/bin/run', false, "'d:/vendor/acme/bin/run'"),
|
||||||
array('c:\\bin\\run', 'd:/vendor/acme/bin/run', false, "'d:/vendor/acme/bin/run'"),
|
array('c:\\bin\\run', 'd:/vendor/acme/bin/run', false, "'d:/vendor/acme/bin/run'"),
|
||||||
array('/foo/bar', '/foo/bar', true, "__DIR__"),
|
array('/foo/bar', '/foo/bar', true, "__DIR__"),
|
||||||
|
array('/foo/bar/', '/foo/bar', true, "__DIR__"),
|
||||||
array('/foo/bar', '/foo/baz', true, "dirname(__DIR__).'/baz'"),
|
array('/foo/bar', '/foo/baz', true, "dirname(__DIR__).'/baz'"),
|
||||||
array('/foo/bin/run', '/foo/vendor/acme/bin/run', true, "dirname(dirname(__DIR__)).'/vendor/acme/bin/run'"),
|
array('/foo/bin/run', '/foo/vendor/acme/bin/run', true, "dirname(dirname(__DIR__)).'/vendor/acme/bin/run'"),
|
||||||
array('/foo/bin/run', '/bar/bin/run', true, "'/bar/bin/run'"),
|
array('/foo/bin/run', '/bar/bin/run', true, "'/bar/bin/run'"),
|
||||||
|
@ -52,6 +53,11 @@ class FilesystemTest extends TestCase
|
||||||
array('/tmp/test', '/tmp', true, "dirname(__DIR__)"),
|
array('/tmp/test', '/tmp', true, "dirname(__DIR__)"),
|
||||||
array('/tmp', '/tmp/test', true, "__DIR__ . '/test'"),
|
array('/tmp', '/tmp/test', true, "__DIR__ . '/test'"),
|
||||||
array('C:/Temp', 'c:\Temp\test', true, "__DIR__ . '/test'"),
|
array('C:/Temp', 'c:\Temp\test', true, "__DIR__ . '/test'"),
|
||||||
|
array('/tmp/test/./', '/tmp/test/', true, '__DIR__'),
|
||||||
|
array('/tmp/test/../vendor', '/tmp/test', true, "dirname(__DIR__).'/test'"),
|
||||||
|
array('/tmp/test/.././vendor', '/tmp/test', true, "dirname(__DIR__).'/test'"),
|
||||||
|
array('C:/Temp', 'c:\Temp\..\..\test', true, "dirname(__DIR__).'/test'"),
|
||||||
|
array('C:/Temp/../..', 'd:\Temp\..\..\test', true, "'d:/test'"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,6 +97,12 @@ class FilesystemTest extends TestCase
|
||||||
array('/tmp', '/tmp/test', "test"),
|
array('/tmp', '/tmp/test', "test"),
|
||||||
array('C:/Temp', 'C:\Temp\test', "test"),
|
array('C:/Temp', 'C:\Temp\test', "test"),
|
||||||
array('C:/Temp', 'c:\Temp\test', "test"),
|
array('C:/Temp', 'c:\Temp\test', "test"),
|
||||||
|
array('/tmp/test/./', '/tmp/test', './', true),
|
||||||
|
array('/tmp/test/../vendor', '/tmp/test', '../test', true),
|
||||||
|
array('/tmp/test/.././vendor', '/tmp/test', '../test', true),
|
||||||
|
array('C:/Temp', 'c:\Temp\..\..\test', "../test", true),
|
||||||
|
array('C:/Temp/../..', 'c:\Temp\..\..\test', "./test", true),
|
||||||
|
array('/tmp', '/tmp/../../test', '/test', true),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue