Ensure proper handling of network shares and URLs in cleanPath()

This commit is contained in:
Kijin Sung 2016-03-15 14:41:21 +09:00
parent 8773b15410
commit ff0df0a14b
2 changed files with 22 additions and 2 deletions

View file

@ -55,19 +55,34 @@ class FilenameFilter
*/
public static function cleanPath($path)
{
if (!preg_match('@^(?:[a-z]:[\\\\/]|\\\\|/)@i', $path))
// Convert relative paths to absolute paths.
if (!preg_match('@^(?:/|[a-z]:[\\\\/]|\\\\|https?:)@i', $path))
{
$path = \RX_BASEDIR . $path;
}
// Convert backslashes to forward slashes.
$path = str_replace('\\', '/', $path);
// Remove querystrings and URL fragments.
$path = preg_replace('@[\?#].+$@', '', $path);
$path = preg_replace('@/{2,}@', '/', $path);
// Remove duplicate slashes, except at the beginning of a URL.
$path = preg_replace('@(?<!^|^http:|^https:)/{2,}@', '/', $path);
// Remove sequences of three or more dots.
$path = preg_replace('@/\.{3,}/@', '/', $path);
// Remove single dots.
$path = preg_replace('@/(\./)+@', '/', $path);
// Remove double dots and the preceding directory.
while (preg_match('@/[^/]+/\.\.(?:/|$)@', $path, $matches))
{
$path = str_replace($matches[0], '/', $path);
}
// Trim trailing slashes.
return rtrim($path, '/');
}
}

View file

@ -56,6 +56,11 @@ class FilenameFilterTest extends \Codeception\TestCase\Test
// Test Windows paths.
$this->assertEquals('C:/Windows/Notepad.exe', FilenameFilter::cleanPath('C:\\Windows\\System32\\..\\Notepad.exe'));
$this->assertEquals('//vboxsrv/hello/world', FilenameFilter::cleanPath('\\\\vboxsrv\\hello\\world'));
// Test absolute URLs.
$this->assertEquals('https://www.rhymix.org/foo/bar', FilenameFilter::cleanPath('https://www.rhymix.org/foo/.//bar'));
$this->assertEquals('//www.rhymix.org/foo/bar', FilenameFilter::cleanPath('//www.rhymix.org/foo/.//bar'));
// Do not remove .. if there is no parent directory.
$this->assertEquals('C:/../foobar', FilenameFilter::cleanPath('C:\\..\foobar\\'));