diff --git a/common/framework/filters/filenamefilter.php b/common/framework/filters/filenamefilter.php index becd5e3f7..dc5fee4eb 100644 --- a/common/framework/filters/filenamefilter.php +++ b/common/framework/filters/filenamefilter.php @@ -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('@(?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\\'));