diff --git a/lib/SimpleSAML/Utils/System.php b/lib/SimpleSAML/Utils/System.php index 6769ae9b6d83597d8e8078856e93560c38d75213..e0e93fab83055f2bd6f0198b96a5cd1f36e691be 100644 --- a/lib/SimpleSAML/Utils/System.php +++ b/lib/SimpleSAML/Utils/System.php @@ -107,7 +107,9 @@ class System /** * Resolve a (possibly) relative path from the given base path. * - * A path which starts with a '/' is assumed to be absolute, all others are assumed to be + * A path which starts with a stream wrapper pattern (e.g. s3://) will not be touched + * and returned as is - regardles of the value given as base path. + * If it starts with a '/' it is assumed to be absolute, all others are assumed to be * relative. The default base path is the root of the SimpleSAMLphp installation. * * @param string $path The path we should resolve. @@ -144,17 +146,21 @@ class System $ret = $base; } - $path = explode('/', $path); - foreach ($path as $d) { - if ($d === '.') { - continue; - } elseif ($d === '..') { - $ret = dirname($ret); - } else { - if ($ret && substr($ret, -1) !== '/') { - $ret .= '/'; + if (static::pathContainsStreamWrapper($path)){ + $ret = $path; + } else { + $path = explode('/', $path); + foreach ($path as $d) { + if ($d === '.') { + continue; + } elseif ($d === '..') { + $ret = dirname($ret); + } else { + if ($ret && substr($ret, -1) !== '/') { + $ret .= '/'; + } + $ret .= $d; } - $ret .= $d; } } @@ -239,4 +245,14 @@ class System return substr($path, 1, 1) === ':' && $letterAsciiValue >= 65 && $letterAsciiValue <= 90; } + + /** + * Check if the supplied path contains a stream wrapper + * @param string $path + * @return bool + */ + private static function pathContainsStreamWrapper($path) + { + return preg_match('/^[\w\d]*:\/{2}/', $path) === 1; + } } diff --git a/tests/lib/SimpleSAML/Utils/SystemTest.php b/tests/lib/SimpleSAML/Utils/SystemTest.php index 99a77ebe08a0890f345b26583cbac427e79fb182..6b2c49b28e91105a413bf08a576a8926452d08e1 100644 --- a/tests/lib/SimpleSAML/Utils/SystemTest.php +++ b/tests/lib/SimpleSAML/Utils/SystemTest.php @@ -99,6 +99,36 @@ class SystemTest extends TestCase $this->assertEquals($expected, $res); } + /** + * @covers \SimpleSAML\Utils\System::resolvePath + * @test + */ + public function testResolvePathAllowsStreamWrappers() + { + $base = '/base/'; + $path = 'vfs://simplesaml'; + + $res = System::resolvePath($path, $base); + $expected = $path; + + $this->assertEquals($expected, $res); + } + + /** + * @covers \SimpleSAML\Utils\System::resolvePath + * @test + */ + public function testResolvePathAllowsAwsS3StreamWrappers() + { + $base = '/base/'; + $path = 's3://bucket-name/key-name'; + + $res = System::resolvePath($path, $base); + $expected = $path; + + $this->assertEquals($expected, $res); + } + /** * @covers \SimpleSAML\Utils\System::writeFile * @test @@ -230,7 +260,6 @@ class SystemTest extends TestCase $this->clearInstance($config, '\SimpleSAML\Configuration'); } - private function setConfigurationTempDir($directory) { $config = Configuration::loadFromArray([