diff --git a/libs/sysplugins/smarty_internal_get_include_path.php b/libs/sysplugins/smarty_internal_get_include_path.php index c85de521..ba971e25 100644 --- a/libs/sysplugins/smarty_internal_get_include_path.php +++ b/libs/sysplugins/smarty_internal_get_include_path.php @@ -27,29 +27,36 @@ class Smarty_Internal_Get_Include_Path */ public static function getIncludePath($dirs, $file, Smarty $smarty) { - static $_include_path = null; + static $_include_path = ''; + static $_include_dirs = array(); static $_has_stream_include = null; - if ($_include_path === null) { - $_include_path = (array) explode(PATH_SEPARATOR, get_include_path()); - foreach ($_include_path as $key => $_path) { - $_include_path[$key] = rtrim($_path, '/\\'); + $_i_path = get_include_path(); + if ($_include_path != $_i_path) { + $_include_path = $_i_path; + $_dirs = (array) explode(PATH_SEPARATOR, $_i_path); + $_include_dirs = array(); + foreach ($_dirs as $_path) { + $_include_dirs[] = rtrim($_path, '/\\'); } $_has_stream_include = function_exists('stream_resolve_include_path'); } // try PHP include_path foreach ($dirs as $dir) { + if ($dir[0] == '/' || $dir[1] == ':') { + $dir = $smarty->_realpath($dir, false); + } if ($dir[0] != '/' && $dir[1] != ':') { - $_d_path = $dir . isset($file) ? $file : ''; + $_d_path = $dir . (isset($file) ? $file : ''); if ($_has_stream_include) { // available since PHP 5.3.2 $path = stream_resolve_include_path($_d_path); if ($path !== false && is_file($path)) { - return $smarty->_realpath($path); + return $smarty->_realpath($path, true); } } - foreach ($_include_path as $_i_path) { + foreach ($_include_dirs as $_i_path) { if (is_file($_i_path . DS . $_d_path)) { - return $smarty->_realpath($_i_path . DS . $_d_path); + return $smarty->_realpath($_i_path . DS . $_d_path, true); } } } diff --git a/libs/sysplugins/smarty_security.php b/libs/sysplugins/smarty_security.php index e52ec497..c916bf5f 100644 --- a/libs/sysplugins/smarty_security.php +++ b/libs/sysplugins/smarty_security.php @@ -238,6 +238,20 @@ class Smarty_Security */ protected $_trusted_dir = null; + /** + * Cache for $_include_path lookup + * + * @var string + */ + protected $_include_path = ''; + + /** + * Cache for $_include_array lookup + * + * @var array + */ + protected $_include_dir = array(); + /** * @param Smarty $smarty */ @@ -356,9 +370,10 @@ class Smarty_Security { // check for internal always required tags if (in_array($tag_name, array('assign', 'call', 'private_filter', 'private_block_plugin', - 'private_function_plugin', 'private_object_block_function', 'private_object_function', - 'private_registered_function', 'private_registered_block', 'private_special_variable', - 'private_print_expression', 'private_modifier'))) { + 'private_function_plugin', 'private_object_block_function', + 'private_object_function', 'private_registered_function', + 'private_registered_block', 'private_special_variable', + 'private_print_expression', 'private_modifier'))) { return true; } // check security settings @@ -483,6 +498,26 @@ class Smarty_Security */ public function isTrustedResourceDir($filepath, $isConfig = null) { + if ($this->smarty->use_include_path) { + $_include_path = get_include_path(); + } else { + $_include_path = ''; + } + if ($this->_include_path != $_include_path) { + foreach ($this->_include_dir as $directory) { + unset($this->_resource_dir[$directory]); + } + if ($this->smarty->use_include_path) { + $this->_include_dir = array(); + $_dirs = (array) explode(PATH_SEPARATOR, get_include_path()); + foreach ($_dirs as $_dir) { + $directory = $this->smarty->_realpath($_dir . DS, true); + $this->_include_dir[] = $directory; + $this->_resource_dir[$directory] = true; + } + } + $this->_include_path = $_include_path; + } if ($isConfig !== true) { $_dir = $this->smarty->getTemplateDir(); if ($this->_template_dir !== $_dir) { @@ -490,9 +525,6 @@ class Smarty_Security unset($this->_resource_dir[$directory]); } foreach ($_dir as $directory) { - if ($this->smarty->use_include_path) { - $directory = $this->smarty->_realpath($directory); - } $this->_resource_dir[$directory] = true; } $this->_template_dir = $_dir; @@ -505,9 +537,6 @@ class Smarty_Security unset($this->_resource_dir[$directory]); } foreach ($_dir as $directory) { - if ($this->smarty->use_include_path) { - $directory = $this->smarty->_realpath($directory); - } $this->_resource_dir[$directory] = true; } $this->_config_dir = $_dir; @@ -518,7 +547,7 @@ class Smarty_Security unset($this->_resource_dir[$directory]); } foreach ((array) $this->secure_dir as $directory) { - $directory = $this->smarty->_realpath($directory . DS); + $directory = $this->smarty->_realpath($directory . DS, true); $this->_resource_dir[$directory] = true; } $this->_secure_dir = (array) $this->secure_dir; @@ -538,11 +567,11 @@ class Smarty_Security return true; } // abort if we've reached root - if (($pos = strrpos($directory, DS)) === false || !isset($directory[1])) { + if (!preg_match('#[\\\/][^\\\/]+[\\\/]$#', $directory)) { break; } // bubble up one level - $directory = substr($directory, 0, $pos); + $directory = preg_replace('#[\\\/][^\\\/]+[\\\/]$#', DS, $directory); } // give up @@ -596,12 +625,12 @@ class Smarty_Security $this->_trusted_dir = $this->trusted_dir; foreach ((array) $this->trusted_dir as $directory) { - $directory = $this->smarty->_realpath($directory . DS); + $directory = $this->smarty->_realpath($directory . DS, true); $this->_php_resource_dir[$directory] = true; } } - $_filepath = $this->smarty->_realpath($filepath); + $_filepath = $this->smarty->_realpath($filepath, true); $directory = dirname($_filepath) . DS; $_directory = array(); while (true) {