mirror of
https://github.com/smarty-php/smarty.git
synced 2025-08-06 03:14:27 +02:00
- update for security fixes
- make modifier plugins always trusted
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
12/28/2009
|
||||
- update for security fixes
|
||||
- make modifier plugins always trusted
|
||||
|
||||
12/27/2009
|
||||
--- this is a major update with a couple of internal changes ---
|
||||
- new config file lexer/parser (thanks to Thue Jnaus Kristensen)
|
||||
|
@@ -68,7 +68,6 @@ class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase {
|
||||
$_tpl->forceNocache = true;
|
||||
$_tpl->suppressHeader = true;
|
||||
$_tpl->suppressFileDependency = true;
|
||||
|
||||
if (strpos($this->smarty->block_data[$_name]['source'], '%%%%SMARTY_PARENT%%%%') !== false) {
|
||||
$_output = str_replace('%%%%SMARTY_PARENT%%%%', $compiler->template->extracted_compiled_code, $_tpl->getCompiledTemplate());
|
||||
} elseif ($this->smarty->block_data[$_name]['mode'] == 'prepend') {
|
||||
@@ -78,7 +77,8 @@ class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase {
|
||||
} elseif (!empty($this->smarty->block_data[$_name])) {
|
||||
$_output = $_tpl->getCompiledTemplate();
|
||||
}
|
||||
$compiler->template->properties = array_merge_recursive($compiler->template->properties, $_tpl->properties);
|
||||
$compiler->template->properties['file_dependency'] = array_merge($compiler->template->properties['file_dependency'], $_tpl->properties['file_dependency']);
|
||||
$compiler->template->properties['function'] = array_merge($compiler->template->properties['function'], $_tpl->properties['function']);
|
||||
unset($_tpl);
|
||||
} else {
|
||||
$_output = $compiler->template->extracted_compiled_code;
|
||||
|
@@ -46,7 +46,9 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase {
|
||||
// get compiled code
|
||||
$compiled_tpl = $tpl->getCompiledTemplate();
|
||||
// remove header code
|
||||
$compiled_tpl = preg_replace('/(<\?php \/\*%%SmartyHeaderCode%%\*\/(.+?)\/\*\/%%SmartyHeaderCode%%\*\/\?>\n)/s', '', $compiled_tpl);
|
||||
$compiled_tpl = preg_replace("/(<\?php \/\*%%SmartyHeaderCode:{$tpl->properties['nocache_hash']}%%\*\/(.+?)\/\*\/%%SmartyHeaderCode%%\*\/\?>\n)/s", '', $compiled_tpl);
|
||||
// replace nocache_hash
|
||||
$compiled_tpl = preg_replace("/{$tpl->properties['nocache_hash']}/", $compiler->template->properties['nocache_hash'], $compiled_tpl);
|
||||
$has_compiled_template = true;
|
||||
}
|
||||
}
|
||||
|
@@ -26,32 +26,33 @@ class Smarty_Internal_Compile_Private_Modifier extends Smarty_Internal_CompileBa
|
||||
$this->required_attributes = array('modifier', 'params');
|
||||
// check and get attributes
|
||||
$_attr = $this->_get_attributes($args);
|
||||
// check if modifier allowed
|
||||
if (!$this->compiler->template->security || $this->smarty->security_handler->isTrustedModifier($_attr['modifier'], $this->compiler)) {
|
||||
// check for registered or plugin modifier
|
||||
if (isset($compiler->smarty->registered_plugins['modifier'][$_attr['modifier']])) {
|
||||
$function = $compiler->smarty->registered_plugins['modifier'][$_attr['modifier']][0];
|
||||
if (!is_array($function)) {
|
||||
$output = "{$function}({$_attr['params']})";
|
||||
} else if (is_object($function[0])) {
|
||||
$output = 'call_user_func_array($_smarty_tpl->smarty->registered_plugins[\'modifier\'][\'' . $_attr['modifier'] . '\'][0],array(' . $_attr['params'] . '))';
|
||||
} else {
|
||||
$output = 'call_user_func_array(array(\'' . $function[0] . '\',\'' . $function[1] . '\'),array(' . $_attr['params'] . '))';
|
||||
}
|
||||
} else if ($function = $this->compiler->getPlugin($_attr['modifier'], 'modifier')) {
|
||||
if (!is_array($function)) {
|
||||
$output = "{$function}({$_attr['params']})";
|
||||
} else {
|
||||
$output = 'call_user_func_array(array(\'' . $function[0] . '\',\'' . $function[1] . '\'),array(' . $_attr['params'] . '))';
|
||||
}
|
||||
// check if trusted PHP function
|
||||
} else if (is_callable($_attr['modifier'])) {
|
||||
$output = "{$_attr['modifier']}({$_attr['params']})";
|
||||
// check for registered modifier
|
||||
if (isset($compiler->smarty->registered_plugins['modifier'][$_attr['modifier']])) {
|
||||
$function = $compiler->smarty->registered_plugins['modifier'][$_attr['modifier']][0];
|
||||
if (!is_array($function)) {
|
||||
$output = "{$function}({$_attr['params']})";
|
||||
} else if (is_object($function[0])) {
|
||||
$output = 'call_user_func_array($_smarty_tpl->smarty->registered_plugins[\'modifier\'][\'' . $_attr['modifier'] . '\'][0],array(' . $_attr['params'] . '))';
|
||||
} else {
|
||||
$this->compiler->trigger_template_error ("unknown modifier \"" . $_attr['modifier'] . "\"");
|
||||
$output = 'call_user_func_array(array(\'' . $function[0] . '\',\'' . $function[1] . '\'),array(' . $_attr['params'] . '))';
|
||||
}
|
||||
return $output;
|
||||
// check for plugin modifier
|
||||
} else if ($function = $this->compiler->getPlugin($_attr['modifier'], 'modifier')) {
|
||||
if (!is_array($function)) {
|
||||
$output = "{$function}({$_attr['params']})";
|
||||
} else {
|
||||
$output = 'call_user_func_array(array(\'' . $function[0] . '\',\'' . $function[1] . '\'),array(' . $_attr['params'] . '))';
|
||||
}
|
||||
// check if trusted PHP function
|
||||
} else if (is_callable($_attr['modifier'])) {
|
||||
// check if modifier allowed
|
||||
if (!$this->compiler->template->security || $this->smarty->security_handler->isTrustedModifier($_attr['modifier'], $this->compiler)) {
|
||||
$output = "{$_attr['modifier']}({$_attr['params']})";
|
||||
}
|
||||
} else {
|
||||
$this->compiler->trigger_template_error ("unknown modifier \"" . $_attr['modifier'] . "\"");
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -61,7 +61,7 @@ class Smarty_Internal_Template extends Smarty_Internal_Data {
|
||||
// storage for plugin
|
||||
public $plugin_data = array();
|
||||
// special properties
|
||||
public $properties = array();
|
||||
public $properties = null;
|
||||
// storage for block data
|
||||
public $block_data = array();
|
||||
// required plugins
|
||||
@@ -91,7 +91,9 @@ class Smarty_Internal_Template extends Smarty_Internal_Data {
|
||||
$this->force_cache = $this->smarty->force_cache;
|
||||
$this->security = $this->smarty->security;
|
||||
$this->parent = $_parent;
|
||||
$this->properties['file_dependency'] = array();
|
||||
$this->properties['file_dependency'] = array();
|
||||
$this->properties['nocache_hash'] = '';
|
||||
$this->properties['function'] = array();;
|
||||
// dummy local smarty variable
|
||||
$this->tpl_vars['smarty'] = new Smarty_Variable;
|
||||
// Template resource
|
||||
@@ -329,19 +331,21 @@ class Smarty_Internal_Template extends Smarty_Internal_Data {
|
||||
return false;
|
||||
}
|
||||
// build file dependency string
|
||||
$this->properties['cache_lifetime'] = $this->cache_lifetime;
|
||||
$this->properties['cache_lifetime'] = $this->cache_lifetime;
|
||||
// get text between non-cached items
|
||||
$cache_split = preg_split("!/\*%%SmartyNocache:{$this->properties['nocache_hash']}%%\*\/(.+?)/\*/%%SmartyNocache:{$this->properties['nocache_hash']}%%\*/!s",$this->rendered_content);
|
||||
$cache_split = preg_split("!/\*%%SmartyNocache:{$this->properties['nocache_hash']}%%\*\/(.+?)/\*/%%SmartyNocache:{$this->properties['nocache_hash']}%%\*/!s", $this->rendered_content);
|
||||
// get non-cached items
|
||||
preg_match_all("!/\*%%SmartyNocache:{$this->properties['nocache_hash']}%%\*\/(.+?)/\*/%%SmartyNocache:{$this->properties['nocache_hash']}%%\*/!s",$this->rendered_content,$cache_parts);
|
||||
$output = '';
|
||||
preg_match_all("!/\*%%SmartyNocache:{$this->properties['nocache_hash']}%%\*\/(.+?)/\*/%%SmartyNocache:{$this->properties['nocache_hash']}%%\*/!s", $this->rendered_content, $cache_parts);
|
||||
$output = '';
|
||||
// loop over items, stitch back together
|
||||
foreach($cache_split as $curr_idx => $curr_split) {
|
||||
// escape PHP tags in template content
|
||||
$output .= preg_replace('/(<%|%>|<\?php|<\?|\?>)/', '<?php echo \'$1\'; ?>', $curr_split);
|
||||
// remove nocache tags from cache output
|
||||
$output .= preg_replace("!/\*/?%%SmartyNocache:{$this->properties['nocache_hash']}%%\*/!",'',$cache_parts[0][$curr_idx]);
|
||||
}
|
||||
// escape PHP tags in template content
|
||||
$output .= preg_replace('/(<%|%>|<\?php|<\?|\?>)/', '<?php echo \'$1\'; ?>', $curr_split);
|
||||
if (isset($cache_parts[0][$curr_idx])) {
|
||||
// remove nocache tags from cache output
|
||||
$output .= preg_replace("!/\*/?%%SmartyNocache:{$this->properties['nocache_hash']}%%\*/!", '', $cache_parts[0][$curr_idx]);
|
||||
}
|
||||
}
|
||||
return $this->cache_resource_object->writeCachedContent($this, $this->createPropertyHeader(true) . $output);
|
||||
}
|
||||
|
||||
@@ -489,6 +493,12 @@ class Smarty_Internal_Template extends Smarty_Internal_Data {
|
||||
if ($this->smarty->debugging) {
|
||||
Smarty_Internal_Debug::end_cache($this);
|
||||
}
|
||||
} else {
|
||||
if (!empty($this->properties['nocache_hash']) && !empty($this->parent->properties['nocache_hash'])) {
|
||||
// replace nocache_hash
|
||||
// var_dump($this->properties['nocache_hash'],$this->parent->properties['nocache_hash'],$this->rendered_content);
|
||||
$this->rendered_content = preg_replace("/{$this->properties['nocache_hash']}/", $this->parent->properties['nocache_hash'], $this->rendered_content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -711,9 +721,12 @@ class Smarty_Internal_Template extends Smarty_Internal_Data {
|
||||
*/
|
||||
public function createPropertyHeader ($cache = false)
|
||||
{
|
||||
$directory_security = $this->smarty->direct_access_security ? "<?php /*%%SmartyHeaderCode%%*/ if(!defined('SMARTY_DIR')) exit('no direct access allowed'); /*/%%SmartyHeaderCode%%*/?>\n" : '';
|
||||
// $properties_string = "<?php \$_smarty_tpl->decodeProperties(" . preg_replace('/\s*/', '',var_export($this->properties, true)) . "); ? >\n";
|
||||
$properties_string = "<?php /*%%SmartyHeaderCode%%*/ \$_smarty_tpl->decodeProperties(" . var_export($this->properties, true) . "); /*/%%SmartyHeaderCode%%*/?>\n";
|
||||
$this->properties['fullpath'] = realpath($this->getTemplateFilepath());
|
||||
$properties_string = "<?php /*%%SmartyHeaderCode:{$this->properties['nocache_hash']}%%*/" ;
|
||||
if ($this->smarty->direct_access_security) {
|
||||
$properties_string .= "if(!defined('SMARTY_DIR')) exit('no direct access allowed');\n";
|
||||
}
|
||||
$properties_string .= "\$_smarty_tpl->decodeProperties(" . var_export($this->properties, true) . "); /*/%%SmartyHeaderCode%%*/?>\n";
|
||||
$plugins_string = '';
|
||||
if (!$cache) {
|
||||
if (!empty($this->required_plugins['compiled'])) {
|
||||
@@ -725,15 +738,15 @@ class Smarty_Internal_Template extends Smarty_Internal_Data {
|
||||
$plugins_string .= '?>';
|
||||
}
|
||||
if (!empty($this->required_plugins['cache'])) {
|
||||
$plugins_string .= '<?php echo \'/*%%SmartyNocache%%*/<?php ';
|
||||
$plugins_string .= "<?php echo '/*%%SmartyNocache:{$this->properties['nocache_hash']}%%*/<?php ";
|
||||
foreach($this->required_plugins['cache'] as $plugin_name => $data) {
|
||||
$plugin = 'smarty_' . $data['type'] . '_' . $plugin_name;
|
||||
$plugins_string .= "if (!is_callable(\'{$plugin}\')) include \'{$data['file']}\';\n";
|
||||
}
|
||||
$plugins_string .= "?>/*/%%SmartyNocache%%*/';?>\n";
|
||||
$plugins_string .= "?>/*/%%SmartyNocache:{$this->properties['nocache_hash']}%%*/';?>\n";
|
||||
}
|
||||
}
|
||||
return $directory_security . $properties_string . $plugins_string;
|
||||
return $properties_string . $plugins_string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -741,6 +754,10 @@ class Smarty_Internal_Template extends Smarty_Internal_Data {
|
||||
*/
|
||||
public function decodeProperties ($properties)
|
||||
{
|
||||
// if ($properties['fullpath'] != realpath($this->getTemplateFilepath())) {
|
||||
// throw new Exception('CRC32 collision \'' . $properties['fullpath'] . '\'');
|
||||
// } ;
|
||||
$this->properties['nocache_hash'] = $properties['nocache_hash'];
|
||||
if (isset($properties['cache_lifetime'])) {
|
||||
$this->properties['cache_lifetime'] = $properties['cache_lifetime'];
|
||||
}
|
||||
|
@@ -28,7 +28,7 @@ class Smarty_Internal_TemplateCompilerBase {
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->nocache_hash = md5(uniqid(rand(),true));
|
||||
$this->nocache_hash = uniqid(rand(),true);
|
||||
}
|
||||
// abstract function doCompile($_content);
|
||||
/**
|
||||
@@ -275,7 +275,7 @@ class Smarty_Internal_TemplateCompilerBase {
|
||||
$this->template->required_plugins['compiled'][$plugin_name] = $this->template->required_plugins['compiled'][$plugin_name];
|
||||
}
|
||||
}
|
||||
if ($type = 'modifier') {
|
||||
if ($type == 'modifier') {
|
||||
$this->template->saved_modifer[$plugin_name] = true;
|
||||
}
|
||||
return $this->template->required_plugins_call[$plugin_name][$type];
|
||||
@@ -301,7 +301,7 @@ class Smarty_Internal_TemplateCompilerBase {
|
||||
$this->template->required_plugins['compiled'][$plugin_name]['file'] = $file;
|
||||
$this->template->required_plugins['compiled'][$plugin_name]['type'] = $type;
|
||||
}
|
||||
if ($type = 'modifier') {
|
||||
if ($type == 'modifier') {
|
||||
$this->template->saved_modifer[$plugin_name] = true;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user