- bugfix setTemplateDir('/') and setTemplateDir('') did create wrong absolute filepath https://github.com/smarty-php/smarty/issues/245

- optimization of filepath normalization
This commit is contained in:
uwetews
2016-07-23 22:21:14 +02:00
parent 6d7d36d9a6
commit 2ba2f6e2e7
2 changed files with 155 additions and 86 deletions

View File

@@ -1,4 +1,8 @@
 ===== 3.1.30-dev ===== (xx.xx.xx)  ===== 3.1.30-dev ===== (xx.xx.xx)
23.07.2016
- bugfix setTemplateDir('/') and setTemplateDir('') did create wrong absolute filepath https://github.com/smarty-php/smarty/issues/245
- optimization of filepath normalization
19.07.2016 19.07.2016
- bugfix multiple {include} with relative filepath within {block}{/block} could fail https://github.com/smarty-php/smarty/issues/246 - bugfix multiple {include} with relative filepath within {block}{/block} could fail https://github.com/smarty-php/smarty/issues/246
- bugfix {math} shell injection vulnerability patch provided by Tim Weber - bugfix {math} shell injection vulnerability patch provided by Tim Weber

View File

@@ -121,7 +121,7 @@ class Smarty extends Smarty_Internal_TemplateBase
/** /**
* smarty version * smarty version
*/ */
const SMARTY_VERSION = '3.1.30-dev/86'; const SMARTY_VERSION = '3.1.30-dev/(87)';
/** /**
* define variable scopes * define variable scopes
@@ -292,6 +292,20 @@ class Smarty extends Smarty_Internal_TemplateBase
*/ */
protected $template_dir = array('./templates/'); protected $template_dir = array('./templates/');
/**
* flags for normalized template directory entries
*
* @var array
*/
protected $_processedTemplateDir = array();
/**
* flag if template_dir is normalized
*
* @var bool
*/
public $_templateDirNormalized = false;
/** /**
* joined template directory string used in cache keys * joined template directory string used in cache keys
* *
@@ -299,6 +313,27 @@ class Smarty extends Smarty_Internal_TemplateBase
*/ */
public $_joined_template_dir = null; public $_joined_template_dir = null;
/**
* config directory
*
* @var array
*/
protected $config_dir = array('./configs/');
/**
* flags for normalized template directory entries
*
* @var array
*/
protected $_processedConfigDir = array();
/**
* flag if config_dir is normalized
*
* @var bool
*/
public $_configDirNormalized = false;
/** /**
* joined config directory string used in cache keys * joined config directory string used in cache keys
* *
@@ -334,12 +369,26 @@ class Smarty extends Smarty_Internal_TemplateBase
*/ */
protected $compile_dir = './templates_c/'; protected $compile_dir = './templates_c/';
/**
* flag if template_dir is normalized
*
* @var bool
*/
public $_compileDirNormalized = false;
/** /**
* plugins directory * plugins directory
* *
* @var array * @var array
*/ */
protected $plugins_dir = null; protected $plugins_dir = array();
/**
* flag if plugins_dir is normalized
*
* @var bool
*/
public $_pluginsDirNormalized = false;
/** /**
* cache directory * cache directory
@@ -349,11 +398,11 @@ class Smarty extends Smarty_Internal_TemplateBase
protected $cache_dir = './cache/'; protected $cache_dir = './cache/';
/** /**
* config directory * flag if template_dir is normalized
* *
* @var array * @var bool
*/ */
protected $config_dir = array('./configs/'); public $_cacheDirNormalized = false;
/** /**
* force template compiling? * force template compiling?
@@ -762,12 +811,14 @@ class Smarty extends Smarty_Internal_TemplateBase
*/ */
public function setTemplateDir($template_dir, $isConfig = false) public function setTemplateDir($template_dir, $isConfig = false)
{ {
$type = $isConfig ? 'config_dir' : 'template_dir'; if ($isConfig) {
$joined = '_joined_' . $type; $this->config_dir = array();
$this->{$type} = (array) $template_dir; $this->_processedConfigDir = array();
$this->{$joined} = join(' # ', $this->{$type}); } else {
$this->_cache[ $type . '_new' ] = true; $this->template_dir = array();
$this->_cache[ $type ] = false; $this->_processedTemplateDir = array();
}
$this->addTemplateDir($template_dir, null, $isConfig);
return $this; return $this;
} }
@@ -782,16 +833,36 @@ class Smarty extends Smarty_Internal_TemplateBase
*/ */
public function addTemplateDir($template_dir, $key = null, $isConfig = false) public function addTemplateDir($template_dir, $key = null, $isConfig = false)
{ {
$type = $isConfig ? 'config_dir' : 'template_dir'; if ($isConfig) {
$joined = '_joined_' . $type; $processed = &$this->_processedConfigDir;
if (!isset($this->_cache[ $type ])) { $dir = &$this->config_dir;
$this->{$type} = (array) $this->{$type}; $this->_configDirNormalized = false;
$this->{$joined} = join(' # ', $this->{$type}); } else {
$this->_cache[ $type . '_new' ] = true; $processed = &$this->_processedTemplateDir;
$this->_cache[ $type ] = false; $dir = &$this->template_dir;
$this->_templateDirNormalized = false;
}
if (is_array($template_dir)) {
foreach ($template_dir as $k => $v) {
if (is_int($k)) {
// indexes are not merged but appended
$dir[] = $v;
} else {
// string indexes are overridden
$dir[ $k ] = $v;
unset($processed[ $key ]);
}
}
} else {
if ($key !== null) {
// override directory at specified index
$dir[ $key ] = $template_dir;
unset($processed[ $key ]);
} else {
// append new directory
$dir[] = $template_dir;
}
} }
$this->{$joined} .= ' # ' . join(' # ', (array) $template_dir);
$this->_addDir($type, $template_dir, $key);
return $this; return $this;
} }
@@ -805,24 +876,18 @@ class Smarty extends Smarty_Internal_TemplateBase
*/ */
public function getTemplateDir($index = null, $isConfig = false) public function getTemplateDir($index = null, $isConfig = false)
{ {
$type = $isConfig ? 'config_dir' : 'template_dir'; if ($isConfig) {
if (!isset($this->_cache[ $type ])) { $dir = &$this->config_dir;
$joined = '_joined_' . $type; } else {
$this->{$type} = (array) $this->{$type}; $dir = &$this->template_dir;
$this->{$joined} = join(' # ', $this->{$type});
$this->_cache[ $type ] = false;
} }
if ($this->_cache[ $type ] == false) { if ($isConfig ? !$this->_configDirNormalized : !$this->_templateDirNormalized) {
foreach ($this->{$type} as $k => $v) { $this->_nomalizeTemplateConfig($isConfig);
$this->{$type}[ $k ] = $this->_realpath($v . DS, true);
}
$this->_cache[ $type . '_new' ] = true;
$this->_cache[ $type ] = true;
} }
if ($index !== null) { if ($index !== null) {
return isset($this->{$type}[ $index ]) ? $this->{$type}[ $index ] : null; return isset($dir[ $index ]) ? $dir[ $index ] : null;
} }
return $this->{$type}; return $dir;
} }
/** /**
@@ -872,28 +937,24 @@ class Smarty extends Smarty_Internal_TemplateBase
public function setPluginsDir($plugins_dir) public function setPluginsDir($plugins_dir)
{ {
$this->plugins_dir = (array) $plugins_dir; $this->plugins_dir = (array) $plugins_dir;
if (isset($this->_cache[ 'plugins_dir' ])) { $this->_pluginsDirNormalized = false;
unset($this->_cache[ 'plugins_dir' ]);
}
return $this; return $this;
} }
/** /**
* Adds directory of plugin files * Adds directory of plugin files
* *
* @param $plugins_dir * @param null|array $plugins_dir
* *
* @return Smarty current Smarty instance for chaining * @return Smarty current Smarty instance for chaining
*/ */
public function addPluginsDir($plugins_dir) public function addPluginsDir($plugins_dir)
{ {
if (!isset($this->plugins_dir)) { if (empty($this->plugins_dir)) {
$this->plugins_dir = array(SMARTY_PLUGINS_DIR); $this->plugins_dir[] = SMARTY_PLUGINS_DIR;
}
$this->plugins_dir = array_merge((array) $this->plugins_dir, (array) $plugins_dir);
if (isset($this->_cache[ 'plugins_dir' ])) {
unset($this->_cache[ 'plugins_dir' ]);
} }
$this->plugins_dir = array_merge($this->plugins_dir, (array) $plugins_dir);
$this->_pluginsDirNormalized = false;
return $this; return $this;
} }
@@ -904,19 +965,21 @@ class Smarty extends Smarty_Internal_TemplateBase
*/ */
public function getPluginsDir() public function getPluginsDir()
{ {
if (!isset($this->_cache[ 'plugins_dir' ])) { if (empty($this->plugins_dir)) {
if (!isset($this->plugins_dir)) { $this->plugins_dir[] = SMARTY_PLUGINS_DIR;
$this->plugins_dir = array(SMARTY_PLUGINS_DIR); $this->_pluginsDirNormalized = false;
} else { }
$plugins_dir = (array) $this->plugins_dir; if (!$this->_pluginsDirNormalized) {
$this->plugins_dir = array(); if (!is_array($this->plugins_dir)) {
foreach ($plugins_dir as $v) { $this->plugins_dir = (array) $this->plugins_dir;
$this->plugins_dir[] = $this->_realpath($v . DS, true); }
foreach ($this->plugins_dir as $k => $v) {
if (strpos($v, './') !== false || strpos($v, '.\\') !== false) {
$this->plugins_dir[ $k ] = $this->_realpath(rtrim($v, "/\\") . DS, true);
} }
$this->plugins_dir = array_unique($this->plugins_dir);
} }
$this->_cache[ 'plugin_files' ] = array(); $this->_cache[ 'plugin_files' ] = array();
$this->_cache[ 'plugins_dir' ] = true; $this->_pluginsDirNormalized = true;
} }
return $this->plugins_dir; return $this->plugins_dir;
} }
@@ -930,6 +993,7 @@ class Smarty extends Smarty_Internal_TemplateBase
public function setCompileDir($compile_dir) public function setCompileDir($compile_dir)
{ {
$this->_normalizeDir('compile_dir', $compile_dir); $this->_normalizeDir('compile_dir', $compile_dir);
$this->_compileDirNormalized = true;
return $this; return $this;
} }
@@ -940,8 +1004,9 @@ class Smarty extends Smarty_Internal_TemplateBase
*/ */
public function getCompileDir() public function getCompileDir()
{ {
if (!isset($this->_cache[ 'compile_dir' ])) { if (!$this->_compileDirNormalized) {
$this->_normalizeDir('compile_dir', $this->compile_dir); $this->_normalizeDir('compile_dir', $this->compile_dir);
$this->_compileDirNormalized = true;
} }
return $this->compile_dir; return $this->compile_dir;
} }
@@ -956,6 +1021,7 @@ class Smarty extends Smarty_Internal_TemplateBase
public function setCacheDir($cache_dir) public function setCacheDir($cache_dir)
{ {
$this->_normalizeDir('cache_dir', $cache_dir); $this->_normalizeDir('cache_dir', $cache_dir);
$this->_cacheDirNormalized = true;
return $this; return $this;
} }
@@ -966,8 +1032,9 @@ class Smarty extends Smarty_Internal_TemplateBase
*/ */
public function getCacheDir() public function getCacheDir()
{ {
if (!isset($this->_cache[ 'cache_dir' ])) { if (!$this->_cacheDirNormalized) {
$this->_normalizeDir('cache_dir', $this->cache_dir); $this->_normalizeDir('cache_dir', $this->cache_dir);
$this->_cacheDirNormalized = true;
} }
return $this->cache_dir; return $this->cache_dir;
} }
@@ -980,44 +1047,39 @@ class Smarty extends Smarty_Internal_TemplateBase
*/ */
private function _normalizeDir($dirName, $dir) private function _normalizeDir($dirName, $dir)
{ {
$this->{$dirName} = $this->_realpath($dir . DS, true); $this->{$dirName} = $this->_realpath(rtrim($dir, "/\\") . DS, true);
if (!isset(Smarty::$_muted_directories[ $this->{$dirName} ])) { if (!isset(Smarty::$_muted_directories[ $this->{$dirName} ])) {
Smarty::$_muted_directories[ $this->{$dirName} ] = null; Smarty::$_muted_directories[ $this->{$dirName} ] = null;
} }
$this->_cache[ $dirName ] = true;
} }
/** /**
* add directories to given property name * Normalize template_dir or config_dir
*
* @param bool $isConfig true for config_dir
* *
* @param string $dirName directory property name
* @param string|array $dir directory string or array of strings
* @param mixed $key optional key
*/ */
private function _addDir($dirName, $dir, $key = null) private function _nomalizeTemplateConfig($isConfig)
{ {
$rp = $this->_cache[ $dirName ]; if ($isConfig) {
if (is_array($dir)) { $processed = &$this->_processedConfigDir;
$dir = &$this->config_dir;
} else {
$processed = &$this->_processedTemplateDir;
$dir = &$this->template_dir;
}
if (!is_array($dir)) {
$dir = (array) $dir;
}
foreach ($dir as $k => $v) { foreach ($dir as $k => $v) {
$path = $rp ? $this->_realpath($v . DS, true) : $v; if (!isset($processed[ $k ])) {
if (is_int($k)) { $dir[ $k ] = $v = $this->_realpath(rtrim($v, "/\\") . DS, true);
// indexes are not merged but appended $processed[ $k ] = true;
$this->{$dirName}[] = $path;
} else {
// string indexes are overridden
$this->{$dirName}[ $k ] = $path;
}
}
} else {
$path = $rp ? $this->_realpath($dir . DS, true) : $dir;
if ($key !== null) {
// override directory at specified index
$this->{$dirName}[ $key ] = $path;
} else {
// append new directory
$this->{$dirName}[] = $path;
} }
} }
$isConfig ? $this->_configDirNormalized = true : $this->_templateDirNormalized = true;
$isConfig ? $this->_joined_config_dir = join('#', $this->config_dir) :
$this->_joined_template_dir = join('#', $this->template_dir);
} }
/** /**
@@ -1104,7 +1166,8 @@ class Smarty extends Smarty_Internal_TemplateBase
* *
* @return string * @return string
*/ */
public function _getTemplateId($template_name, $cache_id = null, $compile_id = null, $caching = null, Smarty_Internal_Template $template = null) public function _getTemplateId($template_name, $cache_id = null, $compile_id = null, $caching = null,
Smarty_Internal_Template $template = null)
{ {
$template_name = (strpos($template_name, ':') === false) ? "{$this->default_resource_type}:{$template_name}" : $template_name = (strpos($template_name, ':') === false) ? "{$this->default_resource_type}:{$template_name}" :
$template_name; $template_name;
@@ -1114,7 +1177,8 @@ class Smarty extends Smarty_Internal_TemplateBase
if ((isset($template) && strpos($template_name, ':.') !== false) || $this->allow_ambiguous_resources) { if ((isset($template) && strpos($template_name, ':.') !== false) || $this->allow_ambiguous_resources) {
$_templateId = $_templateId =
Smarty_Resource::getUniqueTemplateName((isset($template) ? $template : $this), $template_name) . "#{$cache_id}#{$compile_id}#{$caching}"; Smarty_Resource::getUniqueTemplateName((isset($template) ? $template : $this), $template_name) .
"#{$cache_id}#{$compile_id}#{$caching}";
} else { } else {
$_templateId = $this->_joined_template_dir . "#{$template_name}#{$cache_id}#{$compile_id}#{$caching}"; $_templateId = $this->_joined_template_dir . "#{$template_name}#{$cache_id}#{$compile_id}#{$caching}";
} }
@@ -1378,7 +1442,7 @@ class Smarty extends Smarty_Internal_TemplateBase
* @param $errline * @param $errline
* @param $errcontext * @param $errcontext
* *
* @return boolean * @return bool|void
*/ */
public static function mutingErrorHandler($errno, $errstr, $errfile, $errline, $errcontext) public static function mutingErrorHandler($errno, $errstr, $errfile, $errline, $errcontext)
{ {
@@ -1420,6 +1484,7 @@ class Smarty extends Smarty_Internal_TemplateBase
return false; return false;
} }
} }
return;
} }
/** /**