diff options
-rw-r--r-- | _test/cases/inc/init_fullpath.test.php | 75 | ||||
-rwxr-xr-x | _test/runtests.php | 1 | ||||
-rw-r--r-- | inc/init.php | 64 |
3 files changed, 115 insertions, 25 deletions
diff --git a/_test/cases/inc/init_fullpath.test.php b/_test/cases/inc/init_fullpath.test.php new file mode 100644 index 000000000..e2acc35a5 --- /dev/null +++ b/_test/cases/inc/init_fullpath.test.php @@ -0,0 +1,75 @@ +<?php +require_once DOKU_INC.'inc/init.php'; + +class init_fullpath_test extends UnitTestCase { + + function test_unix_paths(){ + $base = $_SERVER['SCRIPT_FILENAME']; + $_SERVER['SCRIPT_FILENAME'] = '/absolute/path/self.php'; + $GLOBALS['DOKU_UNITTEST_ASSUME_WINDOWS'] = false; + + // paths to check + $tests = array( + '/foo/bar/baz' => '/foo/bar/baz', + '/foo//bar/baz' => '/foo/bar/baz', + '/foo/../bar/baz' => '/bar/baz', + '/foo/./bar/baz' => '/foo/bar/baz', + '/foo/bar/..' => '/foo', + '/foo/bar/../../../baz' => '/baz', + + 'foo/bar/baz' => '/absolute/path/foo/bar/baz', + 'foo//bar/baz' => '/absolute/path/foo/bar/baz', + 'foo/../bar/baz' => '/absolute/path/bar/baz', + 'foo/./bar/baz' => '/absolute/path/foo/bar/baz', + 'foo/bar/..' => '/absolute/path/foo', + 'foo/bar/../../../baz' => '/absolute/baz', + ); + + foreach($tests as $from => $to){ + $info = "Testing '$from' resulted in '".fullpath($from)."'"; + $this->signal('failinfo',$info); + + $this->assertEqual(fullpath($from),$to); + } + + + $_SERVER['SCRIPT_FILENAME'] = $base; + unset($GLOBALS['DOKU_UNITTEST_ASSUME_WINDOWS']); + } + + function test_windows_paths(){ + $base = $_SERVER['SCRIPT_FILENAME']; + $_SERVER['SCRIPT_FILENAME'] = '/absolute/path/self.php'; + $GLOBALS['DOKU_UNITTEST_ASSUME_WINDOWS'] = true; + + // paths to check + $tests = array( + 'c:foo/bar/baz' => 'c:foo/bar/baz', + 'c:foo//bar/baz' => 'c:foo/bar/baz', + 'c:foo/../bar/baz' => 'c:bar/baz', + 'c:foo/./bar/baz' => 'c:foo/bar/baz', + 'c:foo/bar/..' => 'c:foo', + 'c:foo/bar/../../../baz' => 'c:baz', + + '\\\\server\\share/foo/bar/baz' => '\\\\server\\share/foo/bar/baz', + '\\\\server\\share/foo//bar/baz' => '\\\\server\\share/foo/bar/baz', + '\\\\server\\share/foo/../bar/baz' => '\\\\server\\share/bar/baz', + '\\\\server\\share/foo/./bar/baz' => '\\\\server\\share/foo/bar/baz', + '\\\\server\\share/foo/bar/..' => '\\\\server\\share/foo', + '\\\\server\\share/foo/bar/../../../baz' => '\\\\server\\share/baz', + ); + + foreach($tests as $from => $to){ + $info = "Testing '$from' resulted in '".fullpath($from)."'"; + $this->signal('failinfo',$info); + + $this->assertEqual(fullpath($from),$to); + } + + + $_SERVER['SCRIPT_FILENAME'] = $base; + unset($GLOBALS['DOKU_UNITTEST_ASSUME_WINDOWS']); + } + +} +//Setup VIM: ex: et ts=4 enc=utf-8 : diff --git a/_test/runtests.php b/_test/runtests.php index e3489b4cf..c4a4f36b4 100755 --- a/_test/runtests.php +++ b/_test/runtests.php @@ -2,6 +2,7 @@ <?php ini_set('memory_limit','128M'); if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/'); +define('DOKU_UNITTEST',true); require_once(DOKU_INC.'inc/init.php'); require_once(DOKU_INC.'inc/events.php'); diff --git a/inc/init.php b/inc/init.php index 5277206f6..def5d7997 100644 --- a/inc/init.php +++ b/inc/init.php @@ -42,14 +42,12 @@ //prepare config array() global $conf; - if (!defined('DOKU_UNITTEST')) { - $conf = array(); + $conf = array(); - // load the config file(s) - require_once(DOKU_CONF.'dokuwiki.php'); - if(@file_exists(DOKU_CONF.'local.php')){ - require_once(DOKU_CONF.'local.php'); - } + // load the config file(s) + require_once(DOKU_CONF.'dokuwiki.php'); + if(@file_exists(DOKU_CONF.'local.php')){ + require_once(DOKU_CONF.'local.php'); } //prepare language array @@ -443,22 +441,40 @@ EOT; * This function behaves similar to PHP's realpath() but does not resolve * symlinks or accesses upper directories * + * @author Andreas Gohr <andi@splitbrain.org> * @author <richpageau at yahoo dot co dot uk> * @link http://de3.php.net/manual/en/function.realpath.php#75992 */ function fullpath($path){ - $iswin = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'); - $isunc = 0===strpos($path,'\\\\'); - if($iswin) $path = str_replace('\\','/',$path); // windows compatibility - - // check if path begins with "/" or "c:" ie. is absolute - // if it isnt concat with script path - if (!$isunc && - ((!$iswin && $path{0} !== '/') || - ($iswin && $path{1} !== ':'))) { - $base=dirname($_SERVER['SCRIPT_FILENAME']); - $path=$base."/".$path; + static $run = 0; + $root = ''; + $iswin = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' || $GLOBALS['DOKU_UNITTEST_ASSUME_WINDOWS']); + + // find the (indestructable) root of the path - keeps windows stuff intact + if($path{0} == '/'){ + $root = '/'; + }elseif($iswin){ + // match drive letter and UNC paths + if(preg_match('!^([a-zA-z]:)(.*)!',$path,$match)){ + $root = $match[1]; + $path = $match[2]; + }else if(preg_match('!^(\\\\\\\\[^\\\\/]+\\\\[^\\\\/]+[\\\\/])(.*)!',$path,$match)){ + $root = $match[1]; + $path = $match[2]; + } } + $path = str_replace('\\','/',$path); + + // if the given path wasn't absolute already, prepend the script path and retry + if(!$root){ + $base = dirname($_SERVER['SCRIPT_FILENAME']); + $path = $base.'/'.$path; + if($run == 0){ // avoid endless recursion when base isn't absolute for some reason + $run++; + return fullpath($path,1); + } + } + $run = 0; // canonicalize $path=explode('/', $path); @@ -471,15 +487,13 @@ function fullpath($path){ } array_push($newpath, $p); } - $finalpath = implode('/', $newpath); - if($isunc) $finalpath = '//'.$finalpath; - if(!$iswin) $finalpath = '/'.$finalpath; + $finalpath = $root.implode('/', $newpath); - // check then return valid path or filename - if (@file_exists($finalpath)) { - return ($finalpath); + // check for existance (except when unit testing) + if(!defined('DOKU_UNITTEST') && !@file_exists($finalpath)) { + return false; } - else return false; + return $finalpath; } |