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 @@ + '/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 @@ * @author * @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 + static $run = 0; + $root = ''; + $iswin = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' || $GLOBALS['DOKU_UNITTEST_ASSUME_WINDOWS']); - // 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; + // 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; }