mirror of
https://github.com/smarty-php/smarty.git
synced 2025-08-04 18:34:27 +02:00
optimization
This commit is contained in:
@@ -111,7 +111,7 @@ class Smarty extends Smarty_Internal_TemplateBase
|
||||
/**
|
||||
* smarty version
|
||||
*/
|
||||
const SMARTY_VERSION = '3.1.28-dev/27';
|
||||
const SMARTY_VERSION = '3.1.28-dev/28';
|
||||
|
||||
/**
|
||||
* define variable scopes
|
||||
@@ -737,20 +737,6 @@ class Smarty extends Smarty_Internal_TemplateBase
|
||||
*/
|
||||
public $_parserdebug = false;
|
||||
|
||||
/**
|
||||
* Cache of is_file results of loadPlugin()
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $_is_file_cache = array();
|
||||
|
||||
/**
|
||||
* Cache of internal flags
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $_flags = array();
|
||||
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
@@ -793,6 +779,7 @@ class Smarty extends Smarty_Internal_TemplateBase
|
||||
*/
|
||||
public function fetch($template, $cache_id = null, $compile_id = null, $parent = null, $display = false, $merge_tpl_vars = true, $no_output_filter = false)
|
||||
{
|
||||
$this->_cache['core'] = array();
|
||||
if ($cache_id !== null && is_object($cache_id)) {
|
||||
$parent = $cache_id;
|
||||
$cache_id = null;
|
||||
@@ -943,7 +930,8 @@ class Smarty extends Smarty_Internal_TemplateBase
|
||||
$joined = 'joined_' . $type;
|
||||
$this->{$type} = (array) $template_dir;
|
||||
$this->{$joined} = join(' # ', $this->{$type});
|
||||
$this->_flags[$type] = false;
|
||||
$this->_cache[$type . '_new'] = true;
|
||||
$this->_cache[$type] = false;
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -960,10 +948,11 @@ class Smarty extends Smarty_Internal_TemplateBase
|
||||
{
|
||||
$type = $isConfig ? 'config_dir' : 'template_dir';
|
||||
$joined = 'joined_' . $type;
|
||||
if (!isset($this->_flags[$type])) {
|
||||
if (!isset($this->_cache[$type])) {
|
||||
$this->{$type} = (array) $this->{$type};
|
||||
$this->{$joined} = join(' # ', $this->{$type});
|
||||
$this->_flags[$type] = false;
|
||||
$this->_cache[$type . '_new'] = true;
|
||||
$this->_cache[$type] = false;
|
||||
}
|
||||
$this->{$joined} .= ' # ' . join(' # ', (array) $template_dir);
|
||||
$this->_addDir($type, $template_dir, $key);
|
||||
@@ -981,17 +970,18 @@ class Smarty extends Smarty_Internal_TemplateBase
|
||||
public function getTemplateDir($index = null, $isConfig = false)
|
||||
{
|
||||
$type = $isConfig ? 'config_dir' : 'template_dir';
|
||||
if (!isset($this->_flags[$type])) {
|
||||
if (!isset($this->_cache[$type])) {
|
||||
$joined = 'joined_' . $type;
|
||||
$this->{$type} = (array) $this->{$type};
|
||||
$this->{$joined} = join(' # ', $this->{$type});
|
||||
$this->_flags[$type] = false;
|
||||
$this->_cache[$type] = false;
|
||||
}
|
||||
if ($this->_flags[$type] == false) {
|
||||
if ($this->_cache[$type] == false) {
|
||||
foreach ($this->{$type} as $k => $v) {
|
||||
$this->{$type}[$k] = $this->_realpath($v . DS, true);
|
||||
}
|
||||
$this->_flags[$type] = true;
|
||||
$this->_cache[$type . '_new'] = true;
|
||||
$this->_cache[$type] = true;
|
||||
}
|
||||
if ($index !== null) {
|
||||
return isset($this->{$type}[$index]) ? $this->{$type}[$index] : null;
|
||||
@@ -1046,8 +1036,8 @@ class Smarty extends Smarty_Internal_TemplateBase
|
||||
public function setPluginsDir($plugins_dir)
|
||||
{
|
||||
$this->plugins_dir = (array) $plugins_dir;
|
||||
if (isset($this->_flags['plugins_dir'])) {
|
||||
unset($this->_flags['plugins_dir']);
|
||||
if (isset($this->_cache['plugins_dir'])) {
|
||||
unset($this->_cache['plugins_dir']);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
@@ -1065,8 +1055,8 @@ class Smarty extends Smarty_Internal_TemplateBase
|
||||
$this->plugins_dir = array(SMARTY_PLUGINS_DIR);
|
||||
}
|
||||
$this->plugins_dir = array_merge((array) $this->plugins_dir, (array) $plugins_dir);
|
||||
if (isset($this->_flags['plugins_dir'])) {
|
||||
unset($this->_flags['plugins_dir']);
|
||||
if (isset($this->_cache['plugins_dir'])) {
|
||||
unset($this->_cache['plugins_dir']);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
@@ -1078,7 +1068,7 @@ class Smarty extends Smarty_Internal_TemplateBase
|
||||
*/
|
||||
public function getPluginsDir()
|
||||
{
|
||||
if (!isset($this->_flags['plugins_dir'])) {
|
||||
if (!isset($this->_cache['plugins_dir'])) {
|
||||
if (!isset($this->plugins_dir)) {
|
||||
$this->plugins_dir = array(SMARTY_PLUGINS_DIR);
|
||||
} else {
|
||||
@@ -1089,8 +1079,8 @@ class Smarty extends Smarty_Internal_TemplateBase
|
||||
}
|
||||
$this->plugins_dir = array_unique($this->plugins_dir);
|
||||
}
|
||||
$this->_is_file_cache = array();
|
||||
$this->_flags['plugins_dir'] = true;
|
||||
$this->_cache['plugin_files'] = array();
|
||||
$this->_cache['plugins_dir'] = true;
|
||||
}
|
||||
return $this->plugins_dir;
|
||||
}
|
||||
@@ -1108,7 +1098,7 @@ class Smarty extends Smarty_Internal_TemplateBase
|
||||
if (!isset(Smarty::$_muted_directories[$this->compile_dir])) {
|
||||
Smarty::$_muted_directories[$this->compile_dir] = null;
|
||||
}
|
||||
$this->_flags['compile_dir'] = true;
|
||||
$this->_cache['compile_dir'] = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -1119,12 +1109,12 @@ class Smarty extends Smarty_Internal_TemplateBase
|
||||
*/
|
||||
public function getCompileDir()
|
||||
{
|
||||
if (!isset($this->_flags['compile_dir'])) {
|
||||
if (!isset($this->_cache['compile_dir'])) {
|
||||
$this->compile_dir = $this->_realpath($this->compile_dir . DS, true);
|
||||
if (!isset(Smarty::$_muted_directories[$this->compile_dir])) {
|
||||
Smarty::$_muted_directories[$this->compile_dir] = null;
|
||||
}
|
||||
$this->_flags['compile_dir'] = true;
|
||||
$this->_cache['compile_dir'] = true;
|
||||
}
|
||||
return $this->compile_dir;
|
||||
}
|
||||
@@ -1142,7 +1132,7 @@ class Smarty extends Smarty_Internal_TemplateBase
|
||||
if (!isset(Smarty::$_muted_directories[$this->cache_dir])) {
|
||||
Smarty::$_muted_directories[$this->cache_dir] = null;
|
||||
}
|
||||
$this->_flags['cache_dir'] = true;
|
||||
$this->_cache['cache_dir'] = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -1153,12 +1143,12 @@ class Smarty extends Smarty_Internal_TemplateBase
|
||||
*/
|
||||
public function getCacheDir()
|
||||
{
|
||||
if (!isset($this->_flags['cache_dir'])) {
|
||||
if (!isset($this->_cache['cache_dir'])) {
|
||||
$this->cache_dir = $this->_realpath($this->cache_dir . DS, true);
|
||||
if (!isset(Smarty::$_muted_directories[$this->cache_dir])) {
|
||||
Smarty::$_muted_directories[$this->cache_dir] = null;
|
||||
}
|
||||
$this->_flags['cache_dir'] = true;
|
||||
$this->_cache['cache_dir'] = true;
|
||||
}
|
||||
return $this->cache_dir;
|
||||
}
|
||||
@@ -1172,7 +1162,7 @@ class Smarty extends Smarty_Internal_TemplateBase
|
||||
*/
|
||||
private function _addDir($dirName, $dir, $key = null)
|
||||
{
|
||||
$rp = $this->_flags[$dirName];
|
||||
$rp = $this->_cache[$dirName];
|
||||
if (is_array($dir)) {
|
||||
foreach ($dir as $k => $v) {
|
||||
$path = $rp ? $this->_realpath($v . DS, true) : $v;
|
||||
@@ -1393,13 +1383,16 @@ class Smarty extends Smarty_Internal_TemplateBase
|
||||
{
|
||||
static $pattern = null;
|
||||
static $pattern2 = null;
|
||||
if ($realpath !== null && $path[0] !== '/' && $path[1] !== ':') {
|
||||
if ($pattern == null) {
|
||||
$pattern = '#[' . (DS == '/' ? '\\\\' : '/') . ']|([\\\/]([\\\/]|([.]+[\\\/])))#';
|
||||
$pattern2 = '#([\\\/]+[^\\\/]+[\\\/]+[.]([\\\/]+[.])*[.][\\\/]+([.][\\\/]+)*)|([\\\/]+([.][\\\/]+)+)|[\\\/]{2,}|[' .
|
||||
(DS == '/' ? '\\\\' : '/') . ']+#';
|
||||
}
|
||||
if ($realpath === true && $path[0] !== '/' && $path[1] !== ':') {
|
||||
$path = getcwd() . DS . $path;
|
||||
}
|
||||
while (preg_match(isset($pattern) ? $pattern : $pattern = '#([\\\/][.]+[\\\/])|[' . (DS == '/' ? '\\\\' : '/') .
|
||||
']|[\\\/]{2,}#', $path)) {
|
||||
$path = preg_replace(isset($pattern2) ? $pattern2 : $pattern2 = '#([\\\/]+([.][\\\/]+)+)|([\\\/]+([^\\\/]+[\\\/]+){2}([.][.][\\\/]+){2})|([\\\/]+[^\\\/]+[\\\/]+[.][.][\\\/]+)|[\\\/]{2,}|[' .
|
||||
(DS == '/' ? '\\\\' : '/') . ']+#', DS, $path);
|
||||
while (preg_match($pattern, $path)) {
|
||||
$path = preg_replace($pattern2, DS, $path);
|
||||
}
|
||||
if ($realpath === false && ($path[0] == '/' || $path[1] == ':')) {
|
||||
$path = str_ireplace(getcwd(), '.', $path);
|
||||
|
@@ -22,18 +22,21 @@ class Smarty_Internal_Data
|
||||
* @var string
|
||||
*/
|
||||
public $template_class = 'Smarty_Internal_Template';
|
||||
|
||||
/**
|
||||
* template variables
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $tpl_vars = array();
|
||||
|
||||
/**
|
||||
* parent template (if any)
|
||||
*
|
||||
* @var Smarty_Internal_Template
|
||||
*/
|
||||
public $parent = null;
|
||||
|
||||
/**
|
||||
* configuration settings
|
||||
*
|
||||
@@ -41,6 +44,13 @@ class Smarty_Internal_Data
|
||||
*/
|
||||
public $config_vars = array();
|
||||
|
||||
/**
|
||||
* universal cache
|
||||
*
|
||||
* @var array()
|
||||
*/
|
||||
public $_cache = array();
|
||||
|
||||
/**
|
||||
* assigns a Smarty variable
|
||||
*
|
||||
@@ -48,7 +58,8 @@ class Smarty_Internal_Data
|
||||
* @param mixed $value the value to assign
|
||||
* @param boolean $nocache if true any output of this variable will be not cached
|
||||
*
|
||||
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
|
||||
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for
|
||||
* chaining
|
||||
*/
|
||||
public function assign($tpl_var, $value = null, $nocache = false)
|
||||
{
|
||||
@@ -74,7 +85,8 @@ class Smarty_Internal_Data
|
||||
* @param mixed $value the value to assign
|
||||
* @param boolean $nocache if true any output of this variable will be not cached
|
||||
*
|
||||
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
|
||||
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for
|
||||
* chaining
|
||||
*/
|
||||
public function assignGlobal($varname, $value = null, $nocache = false)
|
||||
{
|
||||
@@ -97,7 +109,8 @@ class Smarty_Internal_Data
|
||||
* @param $value
|
||||
* @param boolean $nocache if true any output of this variable will be not cached
|
||||
*
|
||||
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
|
||||
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for
|
||||
* chaining
|
||||
*/
|
||||
public function assignByRef($tpl_var, &$value, $nocache = false)
|
||||
{
|
||||
@@ -117,7 +130,8 @@ class Smarty_Internal_Data
|
||||
* @param boolean $merge flag if array elements shall be merged
|
||||
* @param boolean $nocache if true any output of this variable will be not cached
|
||||
*
|
||||
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
|
||||
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for
|
||||
* chaining
|
||||
*/
|
||||
public function append($tpl_var, $value = null, $merge = false, $nocache = false)
|
||||
{
|
||||
@@ -132,7 +146,8 @@ class Smarty_Internal_Data
|
||||
* @param mixed &$value the referenced value to append
|
||||
* @param boolean $merge flag if array elements shall be merged
|
||||
*
|
||||
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
|
||||
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for
|
||||
* chaining
|
||||
*/
|
||||
public function appendByRef($tpl_var, &$value, $merge = false)
|
||||
{
|
||||
@@ -159,7 +174,8 @@ class Smarty_Internal_Data
|
||||
*
|
||||
* @param string|array $tpl_var the template variable(s) to clear
|
||||
*
|
||||
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
|
||||
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for
|
||||
* chaining
|
||||
*/
|
||||
public function clearAssign($tpl_var)
|
||||
{
|
||||
@@ -177,7 +193,8 @@ class Smarty_Internal_Data
|
||||
/**
|
||||
* clear all the assigned template variables.
|
||||
*
|
||||
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
|
||||
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for
|
||||
* chaining
|
||||
*/
|
||||
public function clearAllAssign()
|
||||
{
|
||||
@@ -192,7 +209,8 @@ class Smarty_Internal_Data
|
||||
* @param string $config_file filename
|
||||
* @param mixed $sections array of section names, single section or null
|
||||
*
|
||||
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
|
||||
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for
|
||||
* chaining
|
||||
*/
|
||||
public function configLoad($config_file, $sections = null)
|
||||
{
|
||||
@@ -247,7 +265,8 @@ class Smarty_Internal_Data
|
||||
*
|
||||
* @param string $varname variable name or null
|
||||
*
|
||||
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
|
||||
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for
|
||||
* chaining
|
||||
*/
|
||||
public function clearConfig($varname = null)
|
||||
{
|
||||
|
@@ -34,19 +34,19 @@ class Smarty_Internal_Extension_LoadPlugin
|
||||
}
|
||||
if (!empty($match[2])) {
|
||||
$file = SMARTY_SYSPLUGINS_DIR . strtolower($plugin_name) . '.php';
|
||||
if (isset($smarty->_is_file_cache[$file])) {
|
||||
if ($smarty->_is_file_cache[$file] !== false) {
|
||||
return $smarty->_is_file_cache[$file];
|
||||
if (isset($smarty->_cache['plugin_files'][$file])) {
|
||||
if ($smarty->_cache['plugin_files'][$file] !== false) {
|
||||
return $smarty->_cache['plugin_files'][$file];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (is_file($file)) {
|
||||
$smarty->_is_file_cache[$file] = $file;
|
||||
$smarty->_cache['plugin_files'][$file] = $file;
|
||||
require_once($file);
|
||||
return $file;
|
||||
} else {
|
||||
$smarty->_is_file_cache[$file] = false;
|
||||
$smarty->_cache['plugin_files'][$file] = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -54,36 +54,50 @@ class Smarty_Internal_Extension_LoadPlugin
|
||||
// plugin filename is expected to be: [type].[name].php
|
||||
$_plugin_filename = "{$match[1]}.{$match[4]}.php";
|
||||
$_lower_filename = strtolower($_plugin_filename);
|
||||
$_different = $_lower_filename != $_plugin_filename;
|
||||
// loop through plugin dirs and find the plugin
|
||||
$names = array();
|
||||
foreach ($smarty->getPluginsDir() as $_plugin_dir) {
|
||||
$names[] = $_plugin_dir . $_plugin_filename;
|
||||
if ($_different) {
|
||||
$names[] = $_plugin_dir . $_lower_filename;
|
||||
}
|
||||
}
|
||||
foreach ($names as $path) {
|
||||
$file = $smarty->use_include_path ? $smarty->_realpath($path, false) : $path;
|
||||
if (isset($smarty->_is_file_cache[$file])) {
|
||||
if ($smarty->_is_file_cache[$file] !== false) {
|
||||
return $smarty->_is_file_cache[$file];
|
||||
if (isset($smarty->_cache['plugin_files'])) {
|
||||
if (isset($smarty->_cache['plugin_files']['plugins_dir'][$_lower_filename])) {
|
||||
if (!$smarty->use_include_path ||
|
||||
$smarty->_cache['plugin_files']['plugins_dir'][$_lower_filename] !== false
|
||||
) {
|
||||
return $smarty->_cache['plugin_files']['plugins_dir'][$_lower_filename];
|
||||
}
|
||||
}
|
||||
if (is_file($file)) {
|
||||
$smarty->_is_file_cache[$file] = $file;
|
||||
require_once($file);
|
||||
return $file;
|
||||
if (!$smarty->use_include_path || Smarty_Internal_Get_Include_Path::isNewIncludePath($smarty)) {
|
||||
unset($smarty->_cache['plugin_files']['include_path']);
|
||||
} else {
|
||||
if (isset($smarty->_cache['plugin_files']['include_path'][$_lower_filename])) {
|
||||
return $smarty->_cache['plugin_files']['include_path'][$_lower_filename];
|
||||
}
|
||||
}
|
||||
}
|
||||
$_file_names = array($_plugin_filename);
|
||||
if ($_lower_filename != $_plugin_filename) {
|
||||
$_file_names[] = $_lower_filename;
|
||||
}
|
||||
$_p_dirs = $smarty->getPluginsDir();
|
||||
if (!isset($smarty->_cache['plugin_files']['plugins_dir'][$_lower_filename])) {
|
||||
// loop through plugin dirs and find the plugin
|
||||
foreach ($_p_dirs as $_plugin_dir) {
|
||||
foreach ($_file_names as $name) {
|
||||
$file = $_plugin_dir . $name;
|
||||
if (is_file($file)) {
|
||||
$smarty->_cache['plugin_files']['plugins_dir'][$_lower_filename] = $file;
|
||||
require_once($file);
|
||||
return $file;
|
||||
}
|
||||
$smarty->_cache['plugin_files']['plugins_dir'][$_lower_filename] = false;
|
||||
}
|
||||
}
|
||||
$smarty->_is_file_cache[$file] = false;
|
||||
}
|
||||
if ($smarty->use_include_path) {
|
||||
// try PHP include_path
|
||||
$path = Smarty_Internal_Get_Include_Path::getIncludePath($names, null, $smarty);
|
||||
if ($path !== false) {
|
||||
$smarty->_is_file_cache[$path] = $path;
|
||||
require_once($path);
|
||||
return $path;
|
||||
foreach ($_file_names as $_file_name) {
|
||||
// try PHP include_path
|
||||
$file = Smarty_Internal_Get_Include_Path::getIncludePath($_p_dirs, $_file_name, $smarty);
|
||||
$smarty->_cache['plugin_files']['include_path'][$_lower_filename] = $file;
|
||||
if ($file !== false) {
|
||||
require_once($file);
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
// no plugin loaded
|
||||
|
@@ -15,6 +15,110 @@
|
||||
*/
|
||||
class Smarty_Internal_Get_Include_Path
|
||||
{
|
||||
/**
|
||||
* include path cache
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
static $_include_path = '';
|
||||
|
||||
/**
|
||||
* include path directory cache
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
static $_include_dirs = array();
|
||||
|
||||
/**
|
||||
* include path directory cache
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
static $_user_dirs = array();
|
||||
|
||||
/**
|
||||
* stream cache
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
static $stream = array();
|
||||
|
||||
/**
|
||||
* stream cache
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
static $isFile = array();
|
||||
|
||||
/**
|
||||
* stream cache
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
static $isPath = array();
|
||||
|
||||
/**
|
||||
* stream cache
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
static $number = array();
|
||||
|
||||
/**
|
||||
* status cache
|
||||
*
|
||||
* @var null
|
||||
*/
|
||||
static $_has_stream_include = null;
|
||||
|
||||
/**
|
||||
* Numger for array index
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
static $counter = 0;
|
||||
|
||||
/**
|
||||
* Check if include path was updated
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
*/
|
||||
public static function isNewIncludePath(Smarty $smarty)
|
||||
{
|
||||
if (!isset(self::$_has_stream_include)) {
|
||||
self::$_has_stream_include = ($smarty->use_include_path === 2) &&
|
||||
function_exists('stream_resolve_include_path');
|
||||
}
|
||||
$_i_path = get_include_path();
|
||||
if (self::$_include_path != $_i_path) {
|
||||
self::$_include_dirs = array();
|
||||
self::$_include_path = $_i_path;
|
||||
$_dirs = (array) explode(PATH_SEPARATOR, $_i_path);
|
||||
foreach ($_dirs as $_path) {
|
||||
if ($_path[0] != '/' && isset($dir[1]) && $dir[1] != ':') {
|
||||
$_path = $smarty->_realpath($_path . DS, true);
|
||||
}
|
||||
if (is_dir($_path)) {
|
||||
self::$_include_dirs[] = $smarty->_realpath($_path . DS, true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* return array with include path directories
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getIncludePathDirs(Smarty $smarty)
|
||||
{
|
||||
Smarty_Internal_Get_Include_Path::isNewIncludePath($smarty);
|
||||
return self::$_include_dirs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return full file path from PHP include_path
|
||||
*
|
||||
@@ -27,37 +131,50 @@ class Smarty_Internal_Get_Include_Path
|
||||
*/
|
||||
public static function getIncludePath($dirs, $file, Smarty $smarty)
|
||||
{
|
||||
static $_include_path = '';
|
||||
static $_include_dirs = array();
|
||||
static $_has_stream_include = null;
|
||||
$_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');
|
||||
}
|
||||
self::isNewIncludePath($smarty);
|
||||
// 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 : '');
|
||||
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, true);
|
||||
}
|
||||
$dir_n = isset(self::$number[$dir]) ? self::$number[$dir] : self::$number[$dir] = self::$counter ++;
|
||||
if (isset(self::$isFile[$dir_n][$file])) {
|
||||
if (self::$isFile[$dir_n][$file]) {
|
||||
return self::$isFile[$dir_n][$file];
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
foreach ($_include_dirs as $_i_path) {
|
||||
if (is_file($_i_path . DS . $_d_path)) {
|
||||
return $smarty->_realpath($_i_path . DS . $_d_path, true);
|
||||
}
|
||||
if (isset(self::$_user_dirs[$dir_n])) {
|
||||
if (false === self::$_user_dirs[$dir_n]) {
|
||||
continue;
|
||||
} else {
|
||||
$_u_dir = self::$_user_dirs[$dir_n];
|
||||
}
|
||||
} else {
|
||||
if ($dir[0] == '/' || $dir[1] == ':') {
|
||||
$_u_dir = str_ireplace(getcwd(), '.', $dir);
|
||||
if ($_u_dir[0] == '/' || $_u_dir[1] == ':') {
|
||||
self::$_user_dirs[$dir_n] = false;
|
||||
continue;
|
||||
}
|
||||
self::$_user_dirs[$dir_n] = $_u_dir;
|
||||
} else {
|
||||
$_u_dir = self::$_user_dirs[$dir_n] = $dir;
|
||||
}
|
||||
}
|
||||
$_d_path = $_u_dir . (isset($file) ? $file : '');
|
||||
if (self::$_has_stream_include) {
|
||||
// available since PHP 5.3.2
|
||||
self::$stream[$_d_path] = isset(self::$stream[$_d_path]) ? self::$stream[$_d_path] : ($path = stream_resolve_include_path($_d_path)) ? is_file($path) : false;
|
||||
if (self::$stream[$_d_path]) {
|
||||
return self::$isFile[$dir_n][$file] = self::$stream[$_d_path];
|
||||
}
|
||||
}
|
||||
foreach (self::$_include_dirs as $key => $_i_path) {
|
||||
$path = self::$isPath[$key][$dir_n] = isset(self::$isPath[$key][$dir_n]) ? self::$isPath[$key][$dir_n] : is_dir($_i_path .
|
||||
$_u_dir) ? $_i_path .
|
||||
substr($_u_dir, 2) : false;
|
||||
$_file = self::$isFile[$dir_n][$file] = ($path && is_file($path . $file)) ? $path . $file : false;
|
||||
if ($_file) {
|
||||
return $_file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -239,11 +239,11 @@ class Smarty_Security
|
||||
protected $_trusted_dir = null;
|
||||
|
||||
/**
|
||||
* Cache for $_include_path lookup
|
||||
* Cache for include path status
|
||||
*
|
||||
* @var string
|
||||
* @var bool
|
||||
*/
|
||||
protected $_include_path = '';
|
||||
protected $_include_path_status = false;
|
||||
|
||||
/**
|
||||
* Cache for $_include_array lookup
|
||||
@@ -271,7 +271,9 @@ class Smarty_Security
|
||||
*/
|
||||
public function isTrustedPhpFunction($function_name, $compiler)
|
||||
{
|
||||
if (isset($this->php_functions) && (empty($this->php_functions) || in_array($function_name, $this->php_functions))) {
|
||||
if (isset($this->php_functions) &&
|
||||
(empty($this->php_functions) || in_array($function_name, $this->php_functions))
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -291,7 +293,9 @@ class Smarty_Security
|
||||
*/
|
||||
public function isTrustedStaticClass($class_name, $compiler)
|
||||
{
|
||||
if (isset($this->static_classes) && (empty($this->static_classes) || in_array($class_name, $this->static_classes))) {
|
||||
if (isset($this->static_classes) &&
|
||||
(empty($this->static_classes) || in_array($class_name, $this->static_classes))
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -329,7 +333,9 @@ class Smarty_Security
|
||||
// fall back
|
||||
return $this->isTrustedStaticClass($class_name, $compiler);
|
||||
}
|
||||
if (isset($allowed[$class_name]) && (empty($allowed[$class_name]) || in_array($name, $allowed[$class_name]))) {
|
||||
if (isset($allowed[$class_name]) &&
|
||||
(empty($allowed[$class_name]) || in_array($name, $allowed[$class_name]))
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -348,7 +354,9 @@ class Smarty_Security
|
||||
*/
|
||||
public function isTrustedPhpModifier($modifier_name, $compiler)
|
||||
{
|
||||
if (isset($this->php_modifiers) && (empty($this->php_modifiers) || in_array($modifier_name, $this->php_modifiers))) {
|
||||
if (isset($this->php_modifiers) &&
|
||||
(empty($this->php_modifiers) || in_array($modifier_name, $this->php_modifiers))
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -434,7 +442,9 @@ class Smarty_Security
|
||||
} else {
|
||||
$compiler->trigger_template_error("modifier '{$modifier_name}' disabled by security setting", $compiler->lex->taglineno);
|
||||
}
|
||||
} elseif (in_array($modifier_name, $this->allowed_modifiers) && !in_array($modifier_name, $this->disabled_modifiers)) {
|
||||
} elseif (in_array($modifier_name, $this->allowed_modifiers) &&
|
||||
!in_array($modifier_name, $this->disabled_modifiers)
|
||||
) {
|
||||
return true;
|
||||
} else {
|
||||
$compiler->trigger_template_error("modifier '{$modifier_name}' not allowed by security setting", $compiler->lex->taglineno);
|
||||
@@ -498,27 +508,23 @@ 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) {
|
||||
if ($this->_include_path_status !== $this->smarty->use_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);
|
||||
$_dirs = Smarty_Internal_Get_Include_Path::getIncludePathDirs($this->smarty);
|
||||
foreach ($_dirs as $directory) {
|
||||
$this->_include_dir[] = $directory;
|
||||
$this->_resource_dir[$directory] = true;
|
||||
}
|
||||
}
|
||||
$this->_include_path = $_include_path;
|
||||
$this->_include_path_status = $this->smarty->use_include_path;
|
||||
}
|
||||
if ($isConfig !== true) {
|
||||
if ($isConfig !== true &&
|
||||
(!isset($this->smarty->_cache['template_dir_new']) || $this->smarty->_cache['template_dir_new'])
|
||||
) {
|
||||
$_dir = $this->smarty->getTemplateDir();
|
||||
if ($this->_template_dir !== $_dir) {
|
||||
foreach ($this->_template_dir as $directory) {
|
||||
@@ -529,8 +535,11 @@ class Smarty_Security
|
||||
}
|
||||
$this->_template_dir = $_dir;
|
||||
}
|
||||
$this->smarty->_cache['template_dir_new'] = false;
|
||||
}
|
||||
if ($isConfig !== false) {
|
||||
if ($isConfig !== false &&
|
||||
(!isset($this->smarty->_cache['config_dir_new']) || $this->smarty->_cache['config_dir_new'])
|
||||
) {
|
||||
$_dir = $this->smarty->getConfigDir();
|
||||
if ($this->_config_dir !== $_dir) {
|
||||
foreach ($this->_config_dir as $directory) {
|
||||
@@ -541,6 +550,7 @@ class Smarty_Security
|
||||
}
|
||||
$this->_config_dir = $_dir;
|
||||
}
|
||||
$this->smarty->_cache['config_dir_new'] = false;
|
||||
}
|
||||
if ($this->_secure_dir !== (array) $this->secure_dir) {
|
||||
foreach ($this->_secure_dir as $directory) {
|
||||
@@ -552,30 +562,8 @@ class Smarty_Security
|
||||
}
|
||||
$this->_secure_dir = (array) $this->secure_dir;
|
||||
}
|
||||
|
||||
$_filepath = $filepath;
|
||||
$directory = dirname($_filepath) . DS;
|
||||
$_directory = array();
|
||||
while (true) {
|
||||
// remember the directory to add it to _resource_dir in case we're successful
|
||||
$_directory[$directory] = true;
|
||||
// test if the directory is trusted
|
||||
if (isset($this->_resource_dir[$directory])) {
|
||||
// merge sub directories of current $directory into _resource_dir to speed up subsequent lookup
|
||||
$this->_resource_dir = array_merge($this->_resource_dir, $_directory);
|
||||
|
||||
return true;
|
||||
}
|
||||
// abort if we've reached root
|
||||
if (!preg_match('#[\\\/][^\\\/]+[\\\/]$#', $directory)) {
|
||||
break;
|
||||
}
|
||||
// bubble up one level
|
||||
$directory = preg_replace('#[\\\/][^\\\/]+[\\\/]$#', DS, $directory);
|
||||
}
|
||||
|
||||
// give up
|
||||
throw new SmartyException("directory '{$_filepath}' not allowed by security setting");
|
||||
$this->_resource_dir = $this->_checkDir($filepath, $this->_resource_dir);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -630,28 +618,8 @@ class Smarty_Security
|
||||
}
|
||||
}
|
||||
|
||||
$_filepath = $this->smarty->_realpath($filepath, true);
|
||||
$directory = dirname($_filepath) . DS;
|
||||
$_directory = array();
|
||||
while (true) {
|
||||
// remember the directory to add it to _resource_dir in case we're successful
|
||||
$_directory[] = $directory;
|
||||
// test if the directory is trusted
|
||||
if (isset($this->_php_resource_dir[$directory])) {
|
||||
// merge sub directories of current $directory into _resource_dir to speed up subsequent lookup
|
||||
$this->_php_resource_dir = array_merge($this->_php_resource_dir, $_directory);
|
||||
|
||||
return true;
|
||||
}
|
||||
// abort if we've reached root
|
||||
if (($pos = strrpos($directory, DS)) === false || !isset($directory[2])) {
|
||||
break;
|
||||
}
|
||||
// bubble up one level
|
||||
$directory = substr($directory, 0, $pos);
|
||||
}
|
||||
|
||||
throw new SmartyException("directory '{$_filepath}' not allowed by security setting");
|
||||
$this->_php_resource_dir = $this->_checkDir($this->smarty->_realpath($filepath, true), $this->_php_resource_dir);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -680,6 +648,41 @@ class Smarty_Security
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if file is inside a valid directory
|
||||
*
|
||||
* @param string $filepath
|
||||
* @param array $dirs valid directories
|
||||
*
|
||||
* @return array
|
||||
* @throws \SmartyException
|
||||
*/
|
||||
private function _checkDir($filepath, $dirs)
|
||||
{
|
||||
$directory = dirname($filepath) . DS;
|
||||
$_directory = array();
|
||||
while (true) {
|
||||
// remember the directory to add it to _resource_dir in case we're successful
|
||||
$_directory[$directory] = true;
|
||||
// test if the directory is trusted
|
||||
if (isset($dirs[$directory])) {
|
||||
// merge sub directories of current $directory into _resource_dir to speed up subsequent lookup
|
||||
$dirs = array_merge($dirs, $_directory);
|
||||
|
||||
return $dirs;
|
||||
}
|
||||
// abort if we've reached root
|
||||
if (!preg_match('#[\\\/][^\\\/]+[\\\/]$#', $directory)) {
|
||||
break;
|
||||
}
|
||||
// bubble up one level
|
||||
$directory = preg_replace('#[\\\/][^\\\/]+[\\\/]$#', DS, $directory);
|
||||
}
|
||||
|
||||
// give up
|
||||
throw new SmartyException("directory '{$filepath}' not allowed by security setting");
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads security class and enables security
|
||||
*
|
||||
@@ -709,5 +712,4 @@ class Smarty_Security
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user