aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--phpBB/common.php10
-rw-r--r--phpBB/includes/functions.php203
2 files changed, 174 insertions, 39 deletions
diff --git a/phpBB/common.php b/phpBB/common.php
index c69ee4395e..f5e81ad1a6 100644
--- a/phpBB/common.php
+++ b/phpBB/common.php
@@ -99,7 +99,15 @@ else
if (defined('IN_CRON'))
{
chdir($phpbb_root_path);
- $phpbb_root_path = getcwd() . '/';
+ if (@function_exists('getcwd'))
+ {
+ $phpbb_root_path = getcwd() . '/';
+ }
+ else
+ {
+ // This is a best guess
+ $phpbb_root_path = pathinfo($_SERVER['SCRIPT_FILENAME'], PATHINFO_DIRNAME) . '/';
+ }
}
if (!file_exists($phpbb_root_path . 'config.' . $phpEx))
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index ebe94adac7..3e89769234 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -378,56 +378,183 @@ if (!function_exists('stripos'))
if (!function_exists('realpath'))
{
- /**
- * Replacement for realpath if it is disabled
- * This function is from the php manual by nospam at savvior dot com
- */
- function phpbb_realpath($path)
+ if (substr(PHP_OS, 0, 3) != 'WIN' && !(bool) ini_get('safe_mode') && function_exists('shell_exec') && trim(`realpath .`))
{
- $translated_path = getenv('PATH_TRANSLATED');
+ /**
+ * @author Chris Smith <chris@project-minerva.org>
+ * @copyright 2006 Project Minerva Team
+ * @param string $path The path which we should attempt to resolve.
+ * @return mixed
+ */
+ function phpbb_realpath($path)
+ {
+ $arg = escapeshellarg($path);
+ return trim(`realpath '$arg'`);
+ }
+ }
+ else
+ {
+ /**
+ * Checks if a path ($path) is absolute or relative
+ *
+ * @param string $path Path to check absoluteness of
+ * @return boolean
+ */
+ function is_absolute($path)
+ {
+ return ($path[0] == '/' || (substr(PHP_OS, 0, 3) == 'WIN' && preg_match('#^[a-z]:/#i', $path))) ? true : false;
+ }
- $translated_path = str_replace('\\', '/', $translated_path);
- $translated_path = str_replace(basename(getenv('PATH_INFO')), '', $translated_path);
+ /**
+ * @author Chris Smith <chris@project-minerva.org>
+ * @copyright 2006 Project Minerva Team
+ * @param string $path The path which we should attempt to resolve.
+ * @return mixed
+ */
+ function phpbb_realpath($path)
+ {
+ // Now to perform funky shizzle
- $translated_path .= '/';
+ // Switch to use UNIX slashes
+ $path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
+ $path_prefix = '';
- if ($path == '.' || $path == './')
- {
- return $translated_path;
- }
+ // Determine what sort of path we have
+ if (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 (isset($_SERVER['SCRIPT_FILENAME']) && !empty($_SERVER['SCRIPT_FILENAME']))
+ {
+ // Warning: If chdir() has been used this will lie!
+ // @todo This has some problems sometime (CLI can create them easily)
+ $path = str_replace(DIRECTORY_SEPARATOR, '/', dirname($_SERVER['SCRIPT_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 = '.';
+ }
+ }
- // now check for back directory
- $translated_path .= $path;
+ // Remove any repeated slashes
+ $path = preg_replace('#/{2,}#', '/', $path);
- $dirs = explode('/', $translated_path);
+ // Remove the slashes from the start and end of the path
+ $path = trim($path, '/');
- foreach ($dirs as $key => $value)
- {
- if ($value == '..')
+ // Break the string into little bits for us to nibble on
+ $bits = explode('/', $path);
+
+ // Remove any . in the path
+ $bits = array_diff($bits, array('.'));
+
+ // Lets get looping, run over and resolve any .. (up directory)
+ for ($i = 0, $max = sizeof($bits); $i < $max; $i++)
{
- $dirs[$key] = '';
- $dirs[$key - 2] = '';
+ // @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) // ie. !isset($bits[$i - 1]) && $absolute
+ {
+ // We have an absolute path trying to descend above the root of the filesystem
+ // ... Error!
+ return false;
+ }
+ }
}
- }
- $translated_path = '';
+ // Prepend the path prefix
+ array_unshift($bits, $path_prefix);
- foreach ($dirs as $key => $value)
- {
- if (strlen($value) > 0)
+ $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...
+ // @interal The slash in is_dir() gets around an open_basedir restriction
+ if (!@file_exists($resolved) || (!is_dir($resolved . '/') && !is_file($resolved)))
{
- $translated_path .= $value . '/';
+ return false;
}
- }
- $translated_path = substr($translated_path, 0, strlen($translated_path) - 1);
+ // Put the slashes back to the native operating systems slashes
+ $resolved = str_replace('/', DIRECTORY_SEPARATOR, $resolved);
- if (is_dir($translated_path) || is_file($translated_path))
- {
- return $translated_path;
+ return $resolved; // We got here, in the end!
}
-
- return false;
}
}
else
@@ -1919,7 +2046,7 @@ function decode_message(&$message, $bbcode_uid = '')
*/
function generate_text_for_display($text, $uid, $bitfield, $flags)
{
- global $__bbcode;
+ static $bbcode;
if (!$text)
{
@@ -1937,14 +2064,14 @@ function generate_text_for_display($text, $uid, $bitfield, $flags)
if (empty($__bbcode))
{
- $__bbcode = new bbcode($bitfield);
+ $bbcode = new bbcode($bitfield);
}
else
{
- $__bbcode->bbcode($bitfield);
+ $bbcode->bbcode($bitfield);
}
- $__bbcode->bbcode_second_pass($text, $uid);
+ $bbcode->bbcode_second_pass($text, $uid);
}
$text = smiley_text($text, !($flags & 2));