public function test_includephp_absolute() { global $phpbb_root_path; $path_to_php = str_replace('\\', '/', dirname(__FILE__)) . '/templates/_dummy_include.php.inc'; $this->assertTrue(phpbb_is_absolute($path_to_php)); $template_text = "Path is absolute.\n<!-- INCLUDEPHP {$path_to_php} -->"; $cache_dir = $phpbb_root_path . 'cache/'; $fp = fopen($cache_dir . 'includephp_absolute.html', 'w'); fputs($fp, $template_text); fclose($fp); $this->setup_engine(array('tpl_allow_php' => true)); $this->template->set_custom_style('tests', $cache_dir); $this->run_template('includephp_absolute.html', array(), array(), array(), "Path is absolute.\ntesting included php"); $this->template->set_filenames(array('test' => 'includephp_absolute.html')); $this->assertEquals("Path is absolute.\ntesting included php", $this->display('test'), "Testing INCLUDEPHP"); }
/** * @author Chris Smith <*****@*****.**> * @copyright 2006 Project Minerva Team * @param string $path The path which we should attempt to resolve. * @return mixed */ function phpbb_own_realpath($path) { global $request; // Now to perform funky shizzle // Switch to use UNIX slashes $path = str_replace(DIRECTORY_SEPARATOR, '/', $path); $path_prefix = ''; // Determine what sort of path we have if (phpbb_is_absolute($path)) { $absolute = true; if ($path[0] == '/') { // Absolute path, *NIX style $path_prefix = ''; } else { // Absolute path, Windows style // Remove the drive letter and colon $path_prefix = $path[0] . ':'; $path = substr($path, 2); } } else { // Relative Path // Prepend the current working directory if (function_exists('getcwd')) { // This is the best method, hopefully it is enabled! $path = str_replace(DIRECTORY_SEPARATOR, '/', getcwd()) . '/' . $path; $absolute = true; if (preg_match('#^[a-z]:#i', $path)) { $path_prefix = $path[0] . ':'; $path = substr($path, 2); } else { $path_prefix = ''; } } else { if ($request->server('SCRIPT_FILENAME')) { // Warning: If chdir() has been used this will lie! // Warning: This has some problems sometime (CLI can create them easily) $filename = htmlspecialchars_decode($request->server('SCRIPT_FILENAME')); $path = str_replace(DIRECTORY_SEPARATOR, '/', dirname($filename)) . '/' . $path; $absolute = true; $path_prefix = ''; } else { // We have no way of getting the absolute path, just run on using relative ones. $absolute = false; $path_prefix = '.'; } } } // Remove any repeated slashes $path = preg_replace('#/{2,}#', '/', $path); // Remove the slashes from the start and end of the path $path = trim($path, '/'); // Break the string into little bits for us to nibble on $bits = explode('/', $path); // Remove any . in the path, renumber array for the loop below $bits = array_values(array_diff($bits, array('.'))); // Lets get looping, run over and resolve any .. (up directory) for ($i = 0, $max = sizeof($bits); $i < $max; $i++) { // @todo Optimise if ($bits[$i] == '..') { if (isset($bits[$i - 1])) { if ($bits[$i - 1] != '..') { // We found a .. and we are able to traverse upwards, lets do it! unset($bits[$i]); unset($bits[$i - 1]); $i -= 2; $max -= 2; $bits = array_values($bits); } } else { if ($absolute) { // We have an absolute path trying to descend above the root of the filesystem // ... Error! return false; } } } } // Prepend the path prefix array_unshift($bits, $path_prefix); $resolved = ''; $max = sizeof($bits) - 1; // Check if we are able to resolve symlinks, Windows cannot. $symlink_resolve = function_exists('readlink') ? true : false; foreach ($bits as $i => $bit) { if (@is_dir("{$resolved}/{$bit}") || $i == $max && @is_file("{$resolved}/{$bit}")) { // Path Exists if ($symlink_resolve && is_link("{$resolved}/{$bit}") && ($link = readlink("{$resolved}/{$bit}"))) { // Resolved a symlink. $resolved = $link . ($i == $max ? '' : '/'); continue; } } else { // Something doesn't exist here! // This is correct realpath() behaviour but sadly open_basedir and safe_mode make this problematic // return false; } $resolved .= $bit . ($i == $max ? '' : '/'); } // @todo If the file exists fine and open_basedir only has one path we should be able to prepend it // because we must be inside that basedir, the question is where... // @internal The slash in is_dir() gets around an open_basedir restriction if (!@file_exists($resolved) || !@is_dir($resolved . '/') && !is_file($resolved)) { return false; } // Put the slashes back to the native operating systems slashes $resolved = str_replace('/', DIRECTORY_SEPARATOR, $resolved); // Check for DIRECTORY_SEPARATOR at the end (and remove it!) if (substr($resolved, -1) == DIRECTORY_SEPARATOR) { return substr($resolved, 0, -1); } return $resolved; // We got here, in the end! }
/** * @dataProvider is_absolute_data */ public function test_is_absolute($path, $expected) { $this->assertEquals($expected, phpbb_is_absolute($path)); }