From 5f483bb51a72de1b85e6529aa803f7b0725013e0 Mon Sep 17 00:00:00 2001 From: Luke Carrier <luke@carrier.im> Date: Tue, 21 Feb 2017 13:17:42 +0000 Subject: [PATCH] Handle paths with drive letters in System::resolvePath() Note that when normalising the directory separator, using DIRECTORY_SEPARATOR causes tests to fail on non-Windows platforms as its value is (correctly) "/". --- lib/SimpleSAML/Utils/System.php | 23 +++++++++++++++++++++- tests/lib/SimpleSAML/ConfigurationTest.php | 3 +++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/SimpleSAML/Utils/System.php b/lib/SimpleSAML/Utils/System.php index 61e6bfe7e..ddaa7f0aa 100644 --- a/lib/SimpleSAML/Utils/System.php +++ b/lib/SimpleSAML/Utils/System.php @@ -121,13 +121,20 @@ class System $base = $config->getBaseDir(); } + // normalise directory separator + $base = str_replace('\\', '/', $base); + $path = str_replace('\\', '/', $path); + // remove trailing slashes $base = rtrim($base, '/'); + $path = rtrim($path, '/'); // check for absolute path if (substr($path, 0, 1) === '/') { // absolute path. */ $ret = '/'; + } elseif (static::pathContainsDriveLetter($path)) { + $ret = ''; } else { // path relative to base $ret = $base; @@ -140,7 +147,7 @@ class System } elseif ($d === '..') { $ret = dirname($ret); } else { - if (substr($ret, -1) !== '/') { + if ($ret && substr($ret, -1) !== '/') { $ret .= '/'; } $ret .= $d; @@ -204,4 +211,18 @@ class System ); } } + + /** + * Check if the supplied path contains a Windows-style drive letter. + * + * @param string $path + * + * @return bool + */ + private static function pathContainsDriveLetter($path) + { + $letterAsciiValue = ord(strtoupper(substr($path, 0, 1))); + return substr($path, 1, 1) === ':' + && $letterAsciiValue >= 65 && $letterAsciiValue <= 90; + } } diff --git a/tests/lib/SimpleSAML/ConfigurationTest.php b/tests/lib/SimpleSAML/ConfigurationTest.php index 129f658cf..99cdebe34 100644 --- a/tests/lib/SimpleSAML/ConfigurationTest.php +++ b/tests/lib/SimpleSAML/ConfigurationTest.php @@ -201,6 +201,9 @@ class Test_SimpleSAML_Configuration extends PHPUnit_Framework_TestCase $this->assertEquals($c->resolvePath('slash/'), '/basedir/slash'); $this->assertEquals($c->resolvePath('slash//'), '/basedir/slash'); + + $this->assertEquals($c->resolvePath('C:\\otherdir'), 'C:/otherdir'); + $this->assertEquals($c->resolvePath('C:/otherdir'), 'C:/otherdir'); } /** -- GitLab