Finishing up secure mode.

This commit is contained in:
andrey
2001-06-15 14:52:48 +00:00
parent b818436ac3
commit 6d66c568bd
5 changed files with 346 additions and 341 deletions

View File

@@ -210,12 +210,12 @@ function smarty_func_assign($args, &$smarty_obj)
extract($args); extract($args);
if (empty($var)) { if (empty($var)) {
trigger_error("assign: missing 'var' parameter"); $smarty_obj->_trigger_error_msg("assign: missing 'var' parameter");
return; return;
} }
if (empty($value)) { if (empty($value)) {
trigger_error("assign: missing 'value' parameter"); $smarty_obj->_trigger_error_msg("assign: missing 'value' parameter");
return; return;
} }
@@ -423,12 +423,10 @@ function smarty_func_html_select_time()
Function: smarty_func_math Function: smarty_func_math
Purpose: allow math computations in template Purpose: allow math computations in template
\*======================================================================*/ \*======================================================================*/
function smarty_func_math() { function smarty_func_math($args, $smarty_obj) {
$args=func_get_arg(0);
// be sure equation parameter is present // be sure equation parameter is present
if(empty($args["equation"])) { if(empty($args["equation"])) {
trigger_error("math: missing equation parameter"); $smarty_obj->_trigger_error_msg("math: missing equation parameter");
return; return;
} }
@@ -436,7 +434,7 @@ function smarty_func_math() {
// make sure parenthesis are balanced // make sure parenthesis are balanced
if(substr_count($equation,"(") != substr_count($equation,")")) { if(substr_count($equation,"(") != substr_count($equation,")")) {
trigger_error("math: unbalanced parenthesis"); $smarty_obj->_trigger_error_msg("math: unbalanced parenthesis");
return; return;
} }
@@ -445,9 +443,10 @@ function smarty_func_math() {
foreach($match[0] as $curr_var) { foreach($match[0] as $curr_var) {
if(!in_array($curr_var,array_keys($args)) && if(!in_array($curr_var,array_keys($args)) &&
!in_array($curr_var,array('int','abs','ceil','cos','exp','floor','log','log10', !in_array($curr_var,
'max','min','pi','pow','rand','round','sin','sqrt','srand','tan')) ) { array('int','abs','ceil','cos','exp','floor','log','log10',
trigger_error("math: parameter $curr_var not passed as argument"); 'max','min','pi','pow','rand','round','sin','sqrt','srand','tan'))) {
$smarty_obj->_trigger_error_msg("math: parameter $curr_var not passed as argument");
return; return;
} }
} }
@@ -456,11 +455,11 @@ function smarty_func_math() {
if($key != "equation" && $key != "format") { if($key != "equation" && $key != "format") {
// make sure value is not empty // make sure value is not empty
if(strlen($val)==0) { if(strlen($val)==0) {
trigger_error("math: parameter $key is empty"); $smarty_obj->_trigger_error_msg("math: parameter $key is empty");
return; return;
} }
if(!is_numeric($val)) { if(!is_numeric($val)) {
trigger_error("math: parameter $key: is not numeric"); $smarty_obj->_trigger_error_msg("math: parameter $key: is not numeric");
return; return;
} }
$equation = preg_replace("/\b$key\b/",$val,$equation); $equation = preg_replace("/\b$key\b/",$val,$equation);
@@ -479,26 +478,28 @@ function smarty_func_math() {
Function: smarty_func_fetch Function: smarty_func_fetch
Purpose: fetch file, web or ftp data and display results Purpose: fetch file, web or ftp data and display results
\*======================================================================*/ \*======================================================================*/
function smarty_func_fetch($args,&$smarty_obj) { function smarty_func_fetch($args, &$smarty_obj) {
extract($args); extract($args);
if(empty($file)) { if (empty($file)) {
trigger_error("parameter 'file' cannot be empty"); $smarty_obj->_trigger_error_msg("parameter 'file' cannot be empty");
return; return;
} }
if($smarty_obj->security && !preg_match("/^(http|ftp):\/\//",$file)) {
if ($smarty_obj->security && !preg_match('!^(http|ftp)://!', $file)) {
// make sure fetched file comes from secure directory // make sure fetched file comes from secure directory
foreach($smarty_obj->secure_dir as $curr_dir) { foreach ($smarty_obj->secure_dir as $curr_dir) {
if(substr(realpath($file),0,strlen(realpath($curr_dir))) == realpath($curr_dir)) { if (substr(realpath($file), 0, strlen(realpath($curr_dir))) == realpath($curr_dir)) {
$resource_is_secure = true; $resource_is_secure = true;
break; break;
} }
} }
if(!$resource_is_secure) { if (!$resource_is_secure) {
trigger_error("(secure mode) fetching '$file' is not allowed"); $smarty_obj->_trigger_error_msg("(secure mode) fetching '$file' is not allowed");
return; return;
} }
} }
readfile($file); readfile($file);
} }

View File

@@ -98,17 +98,19 @@ class Smarty
// SMARTY_PHP_REMOVE -> remove php tags // SMARTY_PHP_REMOVE -> remove php tags
// SMARTY_PHP_ALLOW -> execute php tags // SMARTY_PHP_ALLOW -> execute php tags
// default: SMARTY_PHP_PASSTHRU // default: SMARTY_PHP_PASSTHRU
var $security = false; // enable template security (default false) var $security = false; // enable template security (default false)
var $secure_dir = array("./templates"); // array of directories considered secure var $secure_dir = array("./templates"); // array of directories considered secure
var $security_settings = array( var $security_settings = array(
"ALLOW_PHP_HANDLING" => false, 'PHP_HANDLING' => false,
"ALLOW_IF_FUNCS" => array('count','is_array'), 'IF_FUNCS' => array('array', 'list',
"ALLOW_INCLUDE_ANY" => false, 'isset', 'empty',
"ALLOW_PHP_TAGS" => false, 'count', 'in_array'),
"ALLOW_MODIFIER_FUNCS" => array('count') 'INCLUDE_ANY' => false,
); 'PHP_TAGS' => false,
'MODIFIER_FUNCS' => array('count')
);
var $left_delimiter = '{'; // template tag delimiters. var $left_delimiter = '{'; // template tag delimiters.
var $right_delimiter = '}'; var $right_delimiter = '}';
@@ -121,8 +123,8 @@ class Smarty
'html_select_time' => 'smarty_func_html_select_time', 'html_select_time' => 'smarty_func_html_select_time',
'math' => 'smarty_func_math', 'math' => 'smarty_func_math',
'fetch' => 'smarty_func_fetch', 'fetch' => 'smarty_func_fetch',
'counter' => 'smarty_func_counter', 'counter' => 'smarty_func_counter',
'assign' => 'smarty_func_assign' 'assign' => 'smarty_func_assign'
); );
var $custom_mods = array( 'lower' => 'strtolower', var $custom_mods = array( 'lower' => 'strtolower',
@@ -162,8 +164,8 @@ class Smarty
var $_conf_obj = null; // configuration object var $_conf_obj = null; // configuration object
var $_smarty_md5 = 'f8d698aea36fcbead2b9d5359ffca76f'; // md5 checksum of the string 'Smarty' var $_smarty_md5 = 'f8d698aea36fcbead2b9d5359ffca76f'; // md5 checksum of the string 'Smarty'
var $_version = '1.4.2'; // Smarty version number var $_version = '1.4.2'; // Smarty version number
var $_extract = false; // flag for custom functions var $_extract = false; // flag for custom functions
/*======================================================================*\ /*======================================================================*\
Function: Smarty Function: Smarty
Purpose: Constructor Purpose: Constructor
@@ -205,7 +207,7 @@ class Smarty
if (!empty($tpl_var) && isset($value)) if (!empty($tpl_var) && isset($value))
$this->_tpl_vars[$tpl_var] = $value; $this->_tpl_vars[$tpl_var] = $value;
} }
$this->_extract = true; $this->_extract = true;
} }
@@ -230,7 +232,7 @@ class Smarty
$this->_tpl_vars[$tpl_var][] = $value; $this->_tpl_vars[$tpl_var][] = $value;
} }
} }
$this->_extract = true; $this->_extract = true;
} }
@@ -426,8 +428,8 @@ class Smarty
/*======================================================================*\ /*======================================================================*\
Function: clear_compile_dir() Function: clear_compile_dir()
Purpose: clears compiled version of specified template resource, Purpose: clears compiled version of specified template resource,
or all compiled template files if one is not specified. or all compiled template files if one is not specified.
This function is for advanced use only, not normally needed. This function is for advanced use only, not normally needed.
\*======================================================================*/ \*======================================================================*/
function clear_compile_dir($tpl_file = null) function clear_compile_dir($tpl_file = null)
@@ -435,23 +437,23 @@ class Smarty
if (!is_dir($this->compile_dir)) if (!is_dir($this->compile_dir))
return false; return false;
if (isset($tpl_file)) { if (isset($tpl_file)) {
// remove compiled template file if it exists // remove compiled template file if it exists
$tpl_file = urlencode($tpl_file).'.php'; $tpl_file = urlencode($tpl_file).'.php';
if (file_exists($this->compile_dir.'/'.$tpl_file)) { if (file_exists($this->compile_dir.'/'.$tpl_file)) {
unlink($this->compile_dir.'/'.$tpl_file); unlink($this->compile_dir.'/'.$tpl_file);
} }
} else { } else {
// remove everything in $compile_dir // remove everything in $compile_dir
$dir_handle = opendir($this->compile_dir); $dir_handle = opendir($this->compile_dir);
while ($curr_file = readdir($dir_handle)) { while ($curr_file = readdir($dir_handle)) {
if ($curr_file == '.' || $curr_dir == '..' || if ($curr_file == '.' || $curr_dir == '..' ||
!is_file($this->compile_dir.'/'.$curr_file)) { !is_file($this->compile_dir.'/'.$curr_file)) {
continue; continue;
} }
unlink($this->compile_dir.'/'.$curr_file); unlink($this->compile_dir.'/'.$curr_file);
} }
closedir($dir_handle); closedir($dir_handle);
} }
return true; return true;
@@ -634,7 +636,7 @@ class Smarty
Purpose: fetch the template source and timestamp Purpose: fetch the template source and timestamp
\*======================================================================*/ \*======================================================================*/
function _fetch_template_source($tpl_path, &$template_source, &$template_timestamp) function _fetch_template_source($tpl_path, &$template_source, &$template_timestamp)
{ {
// split tpl_path by the first colon // split tpl_path by the first colon
$tpl_path_parts = explode(':', $tpl_path, 2); $tpl_path_parts = explode(':', $tpl_path, 2);
@@ -653,20 +655,20 @@ class Smarty
// relative pathname to $template_dir // relative pathname to $template_dir
$resource_name = $this->template_dir.'/'.$resource_name; $resource_name = $this->template_dir.'/'.$resource_name;
} }
// if security is on, make sure template comes from a $secure_dir // if security is on, make sure template comes from a $secure_dir
if($this->security && !$this->security_settings["ALLOW_INCLUDE_ANY"]) { if ($this->security && !$this->security_settings['INCLUDE_ANY']) {
$resource_is_secure = false; $resource_is_secure = false;
foreach($this->secure_dir as $curr_dir) { foreach ($this->secure_dir as $curr_dir) {
if(substr(realpath($resource_name),0,strlen(realpath($curr_dir))) == realpath($curr_dir)) { if (substr(realpath($resource_name),0,strlen(realpath($curr_dir))) == realpath($curr_dir)) {
$resource_is_secure = true; $resource_is_secure = true;
break; break;
} }
} }
if(!$resource_is_secure) { if (!$resource_is_secure) {
$this->_trigger_error_msg("(secure mode) including \"$resource_name\" is not allowed"); $this->_trigger_error_msg("(secure mode) including \"$resource_name\" is not allowed");
return false; return false;
} }
} }
if (file_exists($resource_name) && is_readable($resource_name)) { if (file_exists($resource_name) && is_readable($resource_name)) {
$template_source = $this->_read_file($resource_name); $template_source = $this->_read_file($resource_name);
$template_timestamp = filemtime($resource_name); $template_timestamp = filemtime($resource_name);
@@ -721,8 +723,8 @@ class Smarty
$smarty_compiler->_version = $this->_version; $smarty_compiler->_version = $this->_version;
$smarty_compiler->prefilter_funcs = $this->prefilter_funcs; $smarty_compiler->prefilter_funcs = $this->prefilter_funcs;
$smarty_compiler->compiler_funcs = $this->compiler_funcs; $smarty_compiler->compiler_funcs = $this->compiler_funcs;
$smarty_compiler->security = $this->security; $smarty_compiler->security = $this->security;
$smarty_compiler->secure_dir = $this->secure_dir; $smarty_compiler->secure_dir = $this->secure_dir;
$smarty_compiler->security_settings = $this->security_settings; $smarty_compiler->security_settings = $this->security_settings;
if ($smarty_compiler->_compile_file($tpl_file, $template_source, $template_compiled)) if ($smarty_compiler->_compile_file($tpl_file, $template_source, $template_compiled))
@@ -818,10 +820,10 @@ class Smarty
$this->_trigger_error_msg("problem writing '$filename.'"); $this->_trigger_error_msg("problem writing '$filename.'");
return false; return false;
} }
// flock doesn't seem to work on several windows platforms (98, NT4, NT5, ?), // flock doesn't seem to work on several windows platforms (98, NT4, NT5, ?),
// so we'll not use it at all in windows. // so we'll not use it at all in windows.
if ( strtoupper(substr(PHP_OS,0,3)) == 'WIN' || (flock($fd, LOCK_EX)) ) { if ( strtoupper(substr(PHP_OS,0,3)) == 'WIN' || (flock($fd, LOCK_EX)) ) {
fwrite( $fd, $contents ); fwrite( $fd, $contents );
fclose($fd); fclose($fd);

View File

@@ -43,7 +43,7 @@ class Smarty_Compiler extends Smarty {
// internal vars // internal vars
var $_sectionelse_stack = array(); // keeps track of whether section had 'else' part var $_sectionelse_stack = array(); // keeps track of whether section had 'else' part
var $_literal_blocks = array(); // keeps literal template blocks var $_literal_blocks = array(); // keeps literal template blocks
var $_php_blocks = array(); // keeps php code blocks var $_php_blocks = array(); // keeps php code blocks
var $_current_file = null; // the current template being compiled var $_current_file = null; // the current template being compiled
var $_current_line_no = 1; // line number for error messages var $_current_line_no = 1; // line number for error messages
@@ -54,18 +54,17 @@ class Smarty_Compiler extends Smarty {
\*======================================================================*/ \*======================================================================*/
function _compile_file($tpl_file, $template_source, &$template_compiled) function _compile_file($tpl_file, $template_source, &$template_compiled)
{ {
if($this->security) {
if($this->security) { // do not allow php syntax to be executed unless specified
// do not allow php syntax to be executed unless specified if ($this->php_handling == SMARTY_PHP_ALLOW &&
if($this->php_handling == SMARTY_PHP_ALLOW && !$this->security_settings['PHP_HANDLING']) {
!$this->security_settings["ALLOW_PHP_HANDLING"]) { $this->php_handling = SMARTY_PHP_PASSTHRU;
$this->php_handling = SMARTY_PHP_PASSTHRU; }
} }
}
// run template source through functions registered in prefilter_funcs // run template source through functions registered in prefilter_funcs
if (is_array($this->prefilter_funcs) && count($this->prefilter_funcs) > 0) { if (is_array($this->prefilter_funcs) && count($this->prefilter_funcs) > 0) {
foreach($this->prefilter_funcs as $prefilter) { foreach ($this->prefilter_funcs as $prefilter) {
if (function_exists($prefilter)) { if (function_exists($prefilter)) {
$template_source = $prefilter($template_source); $template_source = $prefilter($template_source);
} else { } else {
@@ -83,14 +82,14 @@ class Smarty_Compiler extends Smarty {
preg_match_all("!{$ldq}literal{$rdq}(.*?){$ldq}/literal{$rdq}!s", $template_source, $match); preg_match_all("!{$ldq}literal{$rdq}(.*?){$ldq}/literal{$rdq}!s", $template_source, $match);
$this->_literal_blocks = $match[1]; $this->_literal_blocks = $match[1];
$template_source = preg_replace("!{$ldq}literal{$rdq}(.*?){$ldq}/literal{$rdq}!s", $template_source = preg_replace("!{$ldq}literal{$rdq}(.*?){$ldq}/literal{$rdq}!s",
$this->quote_replace($this->left_delimiter.'literal'.$this->right_delimiter), $template_source); $this->quote_replace($this->left_delimiter.'literal'.$this->right_delimiter), $template_source);
/* Pull out the php code blocks. */ /* Pull out the php code blocks. */
preg_match_all("!{$ldq}php{$rdq}(.*?){$ldq}/php{$rdq}!s", $template_source, $match); preg_match_all("!{$ldq}php{$rdq}(.*?){$ldq}/php{$rdq}!s", $template_source, $match);
$this->_php_blocks = $match[1]; $this->_php_blocks = $match[1];
$template_source = preg_replace("!{$ldq}php{$rdq}(.*?){$ldq}/php{$rdq}!s", $template_source = preg_replace("!{$ldq}php{$rdq}(.*?){$ldq}/php{$rdq}!s",
$this->quote_replace($this->left_delimiter.'php'.$this->right_delimiter), $template_source); $this->quote_replace($this->left_delimiter.'php'.$this->right_delimiter), $template_source);
/* Gather all template tags. */ /* Gather all template tags. */
preg_match_all("!{$ldq}\s*(.*?)\s*{$rdq}!s", $template_source, $match); preg_match_all("!{$ldq}\s*(.*?)\s*{$rdq}!s", $template_source, $match);
$template_tags = $match[1]; $template_tags = $match[1];
@@ -150,7 +149,7 @@ class Smarty_Compiler extends Smarty {
for ($i = 0; $i < count($strip_tags); $i++) for ($i = 0; $i < count($strip_tags); $i++)
$template_compiled = preg_replace("!{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}!s", $template_compiled = preg_replace("!{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}!s",
$this->quote_replace($strip_tags_modified[$i]), $this->quote_replace($strip_tags_modified[$i]),
$template_compiled, 1); $template_compiled, 1);
} }
// put header at the top of the compiled template // put header at the top of the compiled template
@@ -180,8 +179,8 @@ class Smarty_Compiler extends Smarty {
) )
(?:\s+(.*))? (?:\s+(.*))?
/xs', $template_tag, $match); /xs', $template_tag, $match);
$tag_command = $match[1]; $tag_command = $match[1];
$tag_args = isset($match[2]) ? $match[2] : ''; $tag_args = isset($match[2]) ? $match[2] : '';
/* If the tag name matches a variable or section property definition, /* If the tag name matches a variable or section property definition,
we simply process it. */ we simply process it. */
@@ -209,12 +208,12 @@ class Smarty_Compiler extends Smarty {
case '/if': case '/if':
return '<?php endif; ?>'; return '<?php endif; ?>';
case 'capture': case 'capture':
return '<?php ob_start(); ?>'; return '<?php ob_start(); ?>';
case '/capture': case '/capture':
return '<?php $this->assign("return", ob_get_contents()); ob_end_clean(); ?>'; return '<?php $this->assign("return", ob_get_contents()); ob_end_clean(); ?>';
case 'ldelim': case 'ldelim':
return $this->left_delimiter; return $this->left_delimiter;
@@ -248,23 +247,23 @@ class Smarty_Compiler extends Smarty {
return "<?php echo '".str_replace("'","\'",$literal_block)."'; ?>\n"; return "<?php echo '".str_replace("'","\'",$literal_block)."'; ?>\n";
case 'php': case 'php':
if($this->security && !$this->security_settings["ALLOW_PHP_TAGS"]) { if ($this->security && !$this->security_settings['PHP_TAGS']) {
$this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING); $this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING);
return; return;
} }
list (,$php_block) = each($this->_php_blocks); list (,$php_block) = each($this->_php_blocks);
$this->_current_line_no += substr_count($php_block, "\n"); $this->_current_line_no += substr_count($php_block, "\n");
return '<?php '.$php_block.' ?>'; return '<?php '.$php_block.' ?>';
case 'insert': case 'insert':
return $this->_compile_insert_tag($tag_args); return $this->_compile_insert_tag($tag_args);
default: default:
if (isset($this->compiler_funcs[$tag_command])) { if (isset($this->compiler_funcs[$tag_command])) {
return $this->_compile_compiler_tag($tag_command, $tag_args); return $this->_compile_compiler_tag($tag_command, $tag_args);
} else if (isset($this->custom_funcs[$tag_command])) { } else if (isset($this->custom_funcs[$tag_command])) {
return $this->_compile_custom_tag($tag_command, $tag_args); return $this->_compile_custom_tag($tag_command, $tag_args);
} else { } else {
$this->_syntax_error("unknown tag - '$tag_command'", E_USER_WARNING); $this->_syntax_error("unknown tag - '$tag_command'", E_USER_WARNING);
return; return;
} }
@@ -273,20 +272,20 @@ class Smarty_Compiler extends Smarty {
/*======================================================================*\ /*======================================================================*\
Function: _compile_compiler_tag Function: _compile_compiler_tag
Purpose: compile the custom compiler tag Purpose: compile the custom compiler tag
\*======================================================================*/ \*======================================================================*/
function _compile_compiler_tag($tag_command, $tag_args) function _compile_compiler_tag($tag_command, $tag_args)
{ {
$function = $this->compiler_funcs[$tag_command]; $function = $this->compiler_funcs[$tag_command];
if (!function_exists($function)) { if (!function_exists($function)) {
$this->_syntax_error("compiler function '$tag_command' is not implemented", E_USER_WARNING); $this->_syntax_error("compiler function '$tag_command' is not implemented", E_USER_WARNING);
return; return;
} }
return '<?php' . $function($tag_args, $this) . ' ?>'; return '<?php' . $function($tag_args, $this) . ' ?>';
} }
/*======================================================================*\ /*======================================================================*\
@@ -348,21 +347,21 @@ class Smarty_Compiler extends Smarty {
$this->_syntax_error("missing 'file' attribute in config_load tag"); $this->_syntax_error("missing 'file' attribute in config_load tag");
} }
if (!empty($attrs['global']) && $attrs['global']) if (!empty($attrs['global']) && $attrs['global'])
$update_parent = true; $update_parent = true;
else else
$update_parent = false; $update_parent = false;
$output = "<?php\n" . $output = "<?php\n" .
"\$_smarty_config = array_merge((array)\$_smarty_config, \$this->_conf_obj->get(".$attrs['file']."));\n"; "\$_smarty_config = array_merge((array)\$_smarty_config, \$this->_conf_obj->get(".$attrs['file']."));\n";
if ($update_parent) if ($update_parent)
$output .= "\$_smarty_config_parent = array_merge((array)\$_smarty_config_parent, \$this->_conf_obj->get(".$attrs['file']."));\n"; $output .= "\$_smarty_config_parent = array_merge((array)\$_smarty_config_parent, \$this->_conf_obj->get(".$attrs['file']."));\n";
if (!empty($attrs['section'])) { if (!empty($attrs['section'])) {
$output .= "\$_smarty_config = array_merge((array)\$_smarty_config, \$this->_conf_obj->get(".$attrs['file'].", ".$attrs['section']."));\n"; $output .= "\$_smarty_config = array_merge((array)\$_smarty_config, \$this->_conf_obj->get(".$attrs['file'].", ".$attrs['section']."));\n";
if ($update_parent) if ($update_parent)
$output .= "\$_smarty_config_parent = array_merge((array)\$_smarty_config_parent, \$this->_conf_obj->get(".$attrs['file'].", ".$attrs['section']."));\n"; $output .= "\$_smarty_config_parent = array_merge((array)\$_smarty_config_parent, \$this->_conf_obj->get(".$attrs['file'].", ".$attrs['section']."));\n";
} }
$output .= '?>'; $output .= '?>';
@@ -382,21 +381,21 @@ class Smarty_Compiler extends Smarty {
$this->_syntax_error("missing 'file' attribute in include tag"); $this->_syntax_error("missing 'file' attribute in include tag");
} }
foreach ($attrs as $arg_name => $arg_value) { foreach ($attrs as $arg_name => $arg_value) {
if ($arg_name == 'file') { if ($arg_name == 'file') {
$include_file = $arg_value; $include_file = $arg_value;
continue; continue;
} }
if (is_bool($arg_value)) if (is_bool($arg_value))
$arg_value = $arg_value ? 'true' : 'false'; $arg_value = $arg_value ? 'true' : 'false';
$arg_list[] = "'$arg_name' => $arg_value"; $arg_list[] = "'$arg_name' => $arg_value";
} }
return "<?php " . return "<?php " .
"\$_smarty_tpl_vars = \$this->_tpl_vars;\n" . "\$_smarty_tpl_vars = \$this->_tpl_vars;\n" .
"\$this->_smarty_include(".$include_file.", array(".implode(',', (array)$arg_list)."), \$_smarty_config);\n" . "\$this->_smarty_include(".$include_file.", array(".implode(',', (array)$arg_list)."), \$_smarty_config);\n" .
"\$this->_tpl_vars = \$_smarty_tpl_vars;\n" . "\$this->_tpl_vars = \$_smarty_tpl_vars;\n" .
"unset(\$_smarty_tpl_vars); ?>"; "unset(\$_smarty_tpl_vars); ?>";
} }
@@ -456,8 +455,8 @@ class Smarty_Compiler extends Smarty {
$output .= "{$section_props}['rownum'] = {$section_props}['index'] + 1;\n"; $output .= "{$section_props}['rownum'] = {$section_props}['index'] + 1;\n";
$output .= "{$section_props}['index_prev'] = {$section_props}['index'] - 1;\n"; $output .= "{$section_props}['index_prev'] = {$section_props}['index'] - 1;\n";
$output .= "{$section_props}['index_next'] = {$section_props}['index'] + 1;\n"; $output .= "{$section_props}['index_next'] = {$section_props}['index'] + 1;\n";
$output .= "{$section_props}['first'] = ({$section_props}['index'] == 0);\n"; $output .= "{$section_props}['first'] = ({$section_props}['index'] == 0);\n";
$output .= "{$section_props}['last'] = ({$section_props}['index'] == {$section_props}['loop']-1);\n"; $output .= "{$section_props}['last'] = ({$section_props}['index'] == {$section_props}['loop']-1);\n";
$output .= "?>"; $output .= "?>";
@@ -485,7 +484,7 @@ class Smarty_Compiler extends Smarty {
$is_arg_stack = array(); $is_arg_stack = array();
for ($i = 0; $i < count($tokens); $i++) { for ($i = 0; $i < count($tokens); $i++) {
$token = &$tokens[$i]; $token = &$tokens[$i];
switch ($token) { switch ($token) {
case 'eq': case 'eq':
@@ -561,14 +560,15 @@ class Smarty_Compiler extends Smarty {
current position for the next iteration. */ current position for the next iteration. */
$i = $is_arg_start; $i = $is_arg_start;
break; break;
default:
if($this->security default:
&& $tokens[$i+1] == '(' if($this->security &&
&& !preg_match("|[^a-zA-Z_-]|",$tokens[$i]) $tokens[$i+1] == '(' &&
&& !in_array($tokens[$i],$this->security_settings["ALLOW_IF_FUNCS"])) { !preg_match("|[^a-zA-Z_]|",$tokens[$i]) &&
$this->_syntax_error("(secure mode) '".$tokens[$i]."' not allowed in if statement"); !in_array($tokens[$i], $this->security_settings['IF_FUNCS'])) {
} $this->_syntax_error("(secure mode) '".$tokens[$i]."' not allowed in if statement");
break; }
break;
} }
} }
@@ -712,11 +712,11 @@ class Smarty_Compiler extends Smarty {
return $attrs; return $attrs;
} }
/*======================================================================*\ /*======================================================================*\
Function: _parse_vars_props Function: _parse_vars_props
Purpose: compile variables and section properties tokens into Purpose: compile variables and section properties tokens into
PHP code PHP code
\*======================================================================*/ \*======================================================================*/
function _parse_vars_props(&$tokens) function _parse_vars_props(&$tokens)
{ {
@@ -752,28 +752,28 @@ class Smarty_Compiler extends Smarty {
\*======================================================================*/ \*======================================================================*/
function _parse_var($var_expr) function _parse_var($var_expr)
{ {
$parts = explode('|', substr($var_expr, 1), 2); $parts = explode('|', substr($var_expr, 1), 2);
$var_ref = $parts[0]; $var_ref = $parts[0];
$modifiers = isset($parts[1]) ? $parts[1] : ''; $modifiers = isset($parts[1]) ? $parts[1] : '';
preg_match_all('!\[\w+(\.\w+)?\]|(->|\.)\w+|^\w+!', $var_ref, $match); preg_match_all('!\[\w+(\.\w+)?\]|(->|\.)\w+|^\w+!', $var_ref, $match);
$indexes = $match[0]; $indexes = $match[0];
$var_name = array_shift($indexes); $var_name = array_shift($indexes);
$output = "\$this->_tpl_vars['$var_name']"; $output = "\$this->_tpl_vars['$var_name']";
foreach ($indexes as $index) { foreach ($indexes as $index) {
if ($index{0} == '[') { if ($index{0} == '[') {
$parts = explode('.', substr($index, 1, -1)); $parts = explode('.', substr($index, 1, -1));
$section = $parts[0]; $section = $parts[0];
$section_prop = isset($parts[1]) ? $parts[1] : 'index'; $section_prop = isset($parts[1]) ? $parts[1] : 'index';
$output .= "[\$this->_sections['$section']['properties']['$section_prop']]"; $output .= "[\$this->_sections['$section']['properties']['$section_prop']]";
} else if ($index{0} == '.') { } else if ($index{0} == '.') {
$output .= "['" . substr($index, 1) . "']"; $output .= "['" . substr($index, 1) . "']";
} else { } else {
$output .= $index; $output .= $index;
} }
} }
$this->_parse_modifiers($output, $modifiers); $this->_parse_modifiers($output, $modifiers);
@@ -788,8 +788,8 @@ class Smarty_Compiler extends Smarty {
function _parse_conf_var($conf_var_expr) function _parse_conf_var($conf_var_expr)
{ {
$parts = explode('|', $conf_var_expr, 2); $parts = explode('|', $conf_var_expr, 2);
$var_ref = $parts[0]; $var_ref = $parts[0];
$modifiers = isset($parts[1]) ? $parts[1] : ''; $modifiers = isset($parts[1]) ? $parts[1] : '';
$var_name = substr($var_ref, 1, -1); $var_name = substr($var_ref, 1, -1);
@@ -808,8 +808,8 @@ class Smarty_Compiler extends Smarty {
function _parse_section_prop($section_prop_expr) function _parse_section_prop($section_prop_expr)
{ {
$parts = explode('|', $section_prop_expr, 2); $parts = explode('|', $section_prop_expr, 2);
$var_ref = $parts[0]; $var_ref = $parts[0];
$modifiers = isset($parts[1]) ? $parts[1] : ''; $modifiers = isset($parts[1]) ? $parts[1] : '';
preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match); preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match);
$section_name = $match[1]; $section_name = $match[1];
@@ -855,13 +855,13 @@ class Smarty_Compiler extends Smarty {
* function name. * function name.
*/ */
if (!isset($mod_func_name)) { if (!isset($mod_func_name)) {
if($this->security && !in_array($modifier_name,$this->security_settings["ALLOW_MODIFIER_FUNCS"])) { if ($this->security && !in_array($modifier_name, $this->security_settings['MODIFIER_FUNCS'])) {
$this->_syntax_error("(secure mode) modifier '$modifier_name' is not allowed", E_USER_WARNING); $this->_syntax_error("(secure mode) modifier '$modifier_name' is not allowed", E_USER_WARNING);
continue; continue;
} else { } else {
$mod_func_name = $modifier_name; $mod_func_name = $modifier_name;
} }
} }
if (!function_exists($mod_func_name)) { if (!function_exists($mod_func_name)) {
$this->_syntax_error("modifier '$modifier_name' is not implemented", E_USER_WARNING); $this->_syntax_error("modifier '$modifier_name' is not implemented", E_USER_WARNING);

View File

@@ -98,17 +98,19 @@ class Smarty
// SMARTY_PHP_REMOVE -> remove php tags // SMARTY_PHP_REMOVE -> remove php tags
// SMARTY_PHP_ALLOW -> execute php tags // SMARTY_PHP_ALLOW -> execute php tags
// default: SMARTY_PHP_PASSTHRU // default: SMARTY_PHP_PASSTHRU
var $security = false; // enable template security (default false) var $security = false; // enable template security (default false)
var $secure_dir = array("./templates"); // array of directories considered secure var $secure_dir = array("./templates"); // array of directories considered secure
var $security_settings = array( var $security_settings = array(
"ALLOW_PHP_HANDLING" => false, 'PHP_HANDLING' => false,
"ALLOW_IF_FUNCS" => array('count','is_array'), 'IF_FUNCS' => array('array', 'list',
"ALLOW_INCLUDE_ANY" => false, 'isset', 'empty',
"ALLOW_PHP_TAGS" => false, 'count', 'in_array'),
"ALLOW_MODIFIER_FUNCS" => array('count') 'INCLUDE_ANY' => false,
); 'PHP_TAGS' => false,
'MODIFIER_FUNCS' => array('count')
);
var $left_delimiter = '{'; // template tag delimiters. var $left_delimiter = '{'; // template tag delimiters.
var $right_delimiter = '}'; var $right_delimiter = '}';
@@ -121,8 +123,8 @@ class Smarty
'html_select_time' => 'smarty_func_html_select_time', 'html_select_time' => 'smarty_func_html_select_time',
'math' => 'smarty_func_math', 'math' => 'smarty_func_math',
'fetch' => 'smarty_func_fetch', 'fetch' => 'smarty_func_fetch',
'counter' => 'smarty_func_counter', 'counter' => 'smarty_func_counter',
'assign' => 'smarty_func_assign' 'assign' => 'smarty_func_assign'
); );
var $custom_mods = array( 'lower' => 'strtolower', var $custom_mods = array( 'lower' => 'strtolower',
@@ -162,8 +164,8 @@ class Smarty
var $_conf_obj = null; // configuration object var $_conf_obj = null; // configuration object
var $_smarty_md5 = 'f8d698aea36fcbead2b9d5359ffca76f'; // md5 checksum of the string 'Smarty' var $_smarty_md5 = 'f8d698aea36fcbead2b9d5359ffca76f'; // md5 checksum of the string 'Smarty'
var $_version = '1.4.2'; // Smarty version number var $_version = '1.4.2'; // Smarty version number
var $_extract = false; // flag for custom functions var $_extract = false; // flag for custom functions
/*======================================================================*\ /*======================================================================*\
Function: Smarty Function: Smarty
Purpose: Constructor Purpose: Constructor
@@ -205,7 +207,7 @@ class Smarty
if (!empty($tpl_var) && isset($value)) if (!empty($tpl_var) && isset($value))
$this->_tpl_vars[$tpl_var] = $value; $this->_tpl_vars[$tpl_var] = $value;
} }
$this->_extract = true; $this->_extract = true;
} }
@@ -230,7 +232,7 @@ class Smarty
$this->_tpl_vars[$tpl_var][] = $value; $this->_tpl_vars[$tpl_var][] = $value;
} }
} }
$this->_extract = true; $this->_extract = true;
} }
@@ -426,8 +428,8 @@ class Smarty
/*======================================================================*\ /*======================================================================*\
Function: clear_compile_dir() Function: clear_compile_dir()
Purpose: clears compiled version of specified template resource, Purpose: clears compiled version of specified template resource,
or all compiled template files if one is not specified. or all compiled template files if one is not specified.
This function is for advanced use only, not normally needed. This function is for advanced use only, not normally needed.
\*======================================================================*/ \*======================================================================*/
function clear_compile_dir($tpl_file = null) function clear_compile_dir($tpl_file = null)
@@ -435,23 +437,23 @@ class Smarty
if (!is_dir($this->compile_dir)) if (!is_dir($this->compile_dir))
return false; return false;
if (isset($tpl_file)) { if (isset($tpl_file)) {
// remove compiled template file if it exists // remove compiled template file if it exists
$tpl_file = urlencode($tpl_file).'.php'; $tpl_file = urlencode($tpl_file).'.php';
if (file_exists($this->compile_dir.'/'.$tpl_file)) { if (file_exists($this->compile_dir.'/'.$tpl_file)) {
unlink($this->compile_dir.'/'.$tpl_file); unlink($this->compile_dir.'/'.$tpl_file);
} }
} else { } else {
// remove everything in $compile_dir // remove everything in $compile_dir
$dir_handle = opendir($this->compile_dir); $dir_handle = opendir($this->compile_dir);
while ($curr_file = readdir($dir_handle)) { while ($curr_file = readdir($dir_handle)) {
if ($curr_file == '.' || $curr_dir == '..' || if ($curr_file == '.' || $curr_dir == '..' ||
!is_file($this->compile_dir.'/'.$curr_file)) { !is_file($this->compile_dir.'/'.$curr_file)) {
continue; continue;
} }
unlink($this->compile_dir.'/'.$curr_file); unlink($this->compile_dir.'/'.$curr_file);
} }
closedir($dir_handle); closedir($dir_handle);
} }
return true; return true;
@@ -634,7 +636,7 @@ class Smarty
Purpose: fetch the template source and timestamp Purpose: fetch the template source and timestamp
\*======================================================================*/ \*======================================================================*/
function _fetch_template_source($tpl_path, &$template_source, &$template_timestamp) function _fetch_template_source($tpl_path, &$template_source, &$template_timestamp)
{ {
// split tpl_path by the first colon // split tpl_path by the first colon
$tpl_path_parts = explode(':', $tpl_path, 2); $tpl_path_parts = explode(':', $tpl_path, 2);
@@ -653,20 +655,20 @@ class Smarty
// relative pathname to $template_dir // relative pathname to $template_dir
$resource_name = $this->template_dir.'/'.$resource_name; $resource_name = $this->template_dir.'/'.$resource_name;
} }
// if security is on, make sure template comes from a $secure_dir // if security is on, make sure template comes from a $secure_dir
if($this->security && !$this->security_settings["ALLOW_INCLUDE_ANY"]) { if ($this->security && !$this->security_settings['INCLUDE_ANY']) {
$resource_is_secure = false; $resource_is_secure = false;
foreach($this->secure_dir as $curr_dir) { foreach ($this->secure_dir as $curr_dir) {
if(substr(realpath($resource_name),0,strlen(realpath($curr_dir))) == realpath($curr_dir)) { if (substr(realpath($resource_name),0,strlen(realpath($curr_dir))) == realpath($curr_dir)) {
$resource_is_secure = true; $resource_is_secure = true;
break; break;
} }
} }
if(!$resource_is_secure) { if (!$resource_is_secure) {
$this->_trigger_error_msg("(secure mode) including \"$resource_name\" is not allowed"); $this->_trigger_error_msg("(secure mode) including \"$resource_name\" is not allowed");
return false; return false;
} }
} }
if (file_exists($resource_name) && is_readable($resource_name)) { if (file_exists($resource_name) && is_readable($resource_name)) {
$template_source = $this->_read_file($resource_name); $template_source = $this->_read_file($resource_name);
$template_timestamp = filemtime($resource_name); $template_timestamp = filemtime($resource_name);
@@ -721,8 +723,8 @@ class Smarty
$smarty_compiler->_version = $this->_version; $smarty_compiler->_version = $this->_version;
$smarty_compiler->prefilter_funcs = $this->prefilter_funcs; $smarty_compiler->prefilter_funcs = $this->prefilter_funcs;
$smarty_compiler->compiler_funcs = $this->compiler_funcs; $smarty_compiler->compiler_funcs = $this->compiler_funcs;
$smarty_compiler->security = $this->security; $smarty_compiler->security = $this->security;
$smarty_compiler->secure_dir = $this->secure_dir; $smarty_compiler->secure_dir = $this->secure_dir;
$smarty_compiler->security_settings = $this->security_settings; $smarty_compiler->security_settings = $this->security_settings;
if ($smarty_compiler->_compile_file($tpl_file, $template_source, $template_compiled)) if ($smarty_compiler->_compile_file($tpl_file, $template_source, $template_compiled))
@@ -818,10 +820,10 @@ class Smarty
$this->_trigger_error_msg("problem writing '$filename.'"); $this->_trigger_error_msg("problem writing '$filename.'");
return false; return false;
} }
// flock doesn't seem to work on several windows platforms (98, NT4, NT5, ?), // flock doesn't seem to work on several windows platforms (98, NT4, NT5, ?),
// so we'll not use it at all in windows. // so we'll not use it at all in windows.
if ( strtoupper(substr(PHP_OS,0,3)) == 'WIN' || (flock($fd, LOCK_EX)) ) { if ( strtoupper(substr(PHP_OS,0,3)) == 'WIN' || (flock($fd, LOCK_EX)) ) {
fwrite( $fd, $contents ); fwrite( $fd, $contents );
fclose($fd); fclose($fd);

View File

@@ -43,7 +43,7 @@ class Smarty_Compiler extends Smarty {
// internal vars // internal vars
var $_sectionelse_stack = array(); // keeps track of whether section had 'else' part var $_sectionelse_stack = array(); // keeps track of whether section had 'else' part
var $_literal_blocks = array(); // keeps literal template blocks var $_literal_blocks = array(); // keeps literal template blocks
var $_php_blocks = array(); // keeps php code blocks var $_php_blocks = array(); // keeps php code blocks
var $_current_file = null; // the current template being compiled var $_current_file = null; // the current template being compiled
var $_current_line_no = 1; // line number for error messages var $_current_line_no = 1; // line number for error messages
@@ -54,18 +54,17 @@ class Smarty_Compiler extends Smarty {
\*======================================================================*/ \*======================================================================*/
function _compile_file($tpl_file, $template_source, &$template_compiled) function _compile_file($tpl_file, $template_source, &$template_compiled)
{ {
if($this->security) {
if($this->security) { // do not allow php syntax to be executed unless specified
// do not allow php syntax to be executed unless specified if ($this->php_handling == SMARTY_PHP_ALLOW &&
if($this->php_handling == SMARTY_PHP_ALLOW && !$this->security_settings['PHP_HANDLING']) {
!$this->security_settings["ALLOW_PHP_HANDLING"]) { $this->php_handling = SMARTY_PHP_PASSTHRU;
$this->php_handling = SMARTY_PHP_PASSTHRU; }
} }
}
// run template source through functions registered in prefilter_funcs // run template source through functions registered in prefilter_funcs
if (is_array($this->prefilter_funcs) && count($this->prefilter_funcs) > 0) { if (is_array($this->prefilter_funcs) && count($this->prefilter_funcs) > 0) {
foreach($this->prefilter_funcs as $prefilter) { foreach ($this->prefilter_funcs as $prefilter) {
if (function_exists($prefilter)) { if (function_exists($prefilter)) {
$template_source = $prefilter($template_source); $template_source = $prefilter($template_source);
} else { } else {
@@ -83,14 +82,14 @@ class Smarty_Compiler extends Smarty {
preg_match_all("!{$ldq}literal{$rdq}(.*?){$ldq}/literal{$rdq}!s", $template_source, $match); preg_match_all("!{$ldq}literal{$rdq}(.*?){$ldq}/literal{$rdq}!s", $template_source, $match);
$this->_literal_blocks = $match[1]; $this->_literal_blocks = $match[1];
$template_source = preg_replace("!{$ldq}literal{$rdq}(.*?){$ldq}/literal{$rdq}!s", $template_source = preg_replace("!{$ldq}literal{$rdq}(.*?){$ldq}/literal{$rdq}!s",
$this->quote_replace($this->left_delimiter.'literal'.$this->right_delimiter), $template_source); $this->quote_replace($this->left_delimiter.'literal'.$this->right_delimiter), $template_source);
/* Pull out the php code blocks. */ /* Pull out the php code blocks. */
preg_match_all("!{$ldq}php{$rdq}(.*?){$ldq}/php{$rdq}!s", $template_source, $match); preg_match_all("!{$ldq}php{$rdq}(.*?){$ldq}/php{$rdq}!s", $template_source, $match);
$this->_php_blocks = $match[1]; $this->_php_blocks = $match[1];
$template_source = preg_replace("!{$ldq}php{$rdq}(.*?){$ldq}/php{$rdq}!s", $template_source = preg_replace("!{$ldq}php{$rdq}(.*?){$ldq}/php{$rdq}!s",
$this->quote_replace($this->left_delimiter.'php'.$this->right_delimiter), $template_source); $this->quote_replace($this->left_delimiter.'php'.$this->right_delimiter), $template_source);
/* Gather all template tags. */ /* Gather all template tags. */
preg_match_all("!{$ldq}\s*(.*?)\s*{$rdq}!s", $template_source, $match); preg_match_all("!{$ldq}\s*(.*?)\s*{$rdq}!s", $template_source, $match);
$template_tags = $match[1]; $template_tags = $match[1];
@@ -150,7 +149,7 @@ class Smarty_Compiler extends Smarty {
for ($i = 0; $i < count($strip_tags); $i++) for ($i = 0; $i < count($strip_tags); $i++)
$template_compiled = preg_replace("!{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}!s", $template_compiled = preg_replace("!{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}!s",
$this->quote_replace($strip_tags_modified[$i]), $this->quote_replace($strip_tags_modified[$i]),
$template_compiled, 1); $template_compiled, 1);
} }
// put header at the top of the compiled template // put header at the top of the compiled template
@@ -180,8 +179,8 @@ class Smarty_Compiler extends Smarty {
) )
(?:\s+(.*))? (?:\s+(.*))?
/xs', $template_tag, $match); /xs', $template_tag, $match);
$tag_command = $match[1]; $tag_command = $match[1];
$tag_args = isset($match[2]) ? $match[2] : ''; $tag_args = isset($match[2]) ? $match[2] : '';
/* If the tag name matches a variable or section property definition, /* If the tag name matches a variable or section property definition,
we simply process it. */ we simply process it. */
@@ -209,12 +208,12 @@ class Smarty_Compiler extends Smarty {
case '/if': case '/if':
return '<?php endif; ?>'; return '<?php endif; ?>';
case 'capture': case 'capture':
return '<?php ob_start(); ?>'; return '<?php ob_start(); ?>';
case '/capture': case '/capture':
return '<?php $this->assign("return", ob_get_contents()); ob_end_clean(); ?>'; return '<?php $this->assign("return", ob_get_contents()); ob_end_clean(); ?>';
case 'ldelim': case 'ldelim':
return $this->left_delimiter; return $this->left_delimiter;
@@ -248,23 +247,23 @@ class Smarty_Compiler extends Smarty {
return "<?php echo '".str_replace("'","\'",$literal_block)."'; ?>\n"; return "<?php echo '".str_replace("'","\'",$literal_block)."'; ?>\n";
case 'php': case 'php':
if($this->security && !$this->security_settings["ALLOW_PHP_TAGS"]) { if ($this->security && !$this->security_settings['PHP_TAGS']) {
$this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING); $this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING);
return; return;
} }
list (,$php_block) = each($this->_php_blocks); list (,$php_block) = each($this->_php_blocks);
$this->_current_line_no += substr_count($php_block, "\n"); $this->_current_line_no += substr_count($php_block, "\n");
return '<?php '.$php_block.' ?>'; return '<?php '.$php_block.' ?>';
case 'insert': case 'insert':
return $this->_compile_insert_tag($tag_args); return $this->_compile_insert_tag($tag_args);
default: default:
if (isset($this->compiler_funcs[$tag_command])) { if (isset($this->compiler_funcs[$tag_command])) {
return $this->_compile_compiler_tag($tag_command, $tag_args); return $this->_compile_compiler_tag($tag_command, $tag_args);
} else if (isset($this->custom_funcs[$tag_command])) { } else if (isset($this->custom_funcs[$tag_command])) {
return $this->_compile_custom_tag($tag_command, $tag_args); return $this->_compile_custom_tag($tag_command, $tag_args);
} else { } else {
$this->_syntax_error("unknown tag - '$tag_command'", E_USER_WARNING); $this->_syntax_error("unknown tag - '$tag_command'", E_USER_WARNING);
return; return;
} }
@@ -273,20 +272,20 @@ class Smarty_Compiler extends Smarty {
/*======================================================================*\ /*======================================================================*\
Function: _compile_compiler_tag Function: _compile_compiler_tag
Purpose: compile the custom compiler tag Purpose: compile the custom compiler tag
\*======================================================================*/ \*======================================================================*/
function _compile_compiler_tag($tag_command, $tag_args) function _compile_compiler_tag($tag_command, $tag_args)
{ {
$function = $this->compiler_funcs[$tag_command]; $function = $this->compiler_funcs[$tag_command];
if (!function_exists($function)) { if (!function_exists($function)) {
$this->_syntax_error("compiler function '$tag_command' is not implemented", E_USER_WARNING); $this->_syntax_error("compiler function '$tag_command' is not implemented", E_USER_WARNING);
return; return;
} }
return '<?php' . $function($tag_args, $this) . ' ?>'; return '<?php' . $function($tag_args, $this) . ' ?>';
} }
/*======================================================================*\ /*======================================================================*\
@@ -348,21 +347,21 @@ class Smarty_Compiler extends Smarty {
$this->_syntax_error("missing 'file' attribute in config_load tag"); $this->_syntax_error("missing 'file' attribute in config_load tag");
} }
if (!empty($attrs['global']) && $attrs['global']) if (!empty($attrs['global']) && $attrs['global'])
$update_parent = true; $update_parent = true;
else else
$update_parent = false; $update_parent = false;
$output = "<?php\n" . $output = "<?php\n" .
"\$_smarty_config = array_merge((array)\$_smarty_config, \$this->_conf_obj->get(".$attrs['file']."));\n"; "\$_smarty_config = array_merge((array)\$_smarty_config, \$this->_conf_obj->get(".$attrs['file']."));\n";
if ($update_parent) if ($update_parent)
$output .= "\$_smarty_config_parent = array_merge((array)\$_smarty_config_parent, \$this->_conf_obj->get(".$attrs['file']."));\n"; $output .= "\$_smarty_config_parent = array_merge((array)\$_smarty_config_parent, \$this->_conf_obj->get(".$attrs['file']."));\n";
if (!empty($attrs['section'])) { if (!empty($attrs['section'])) {
$output .= "\$_smarty_config = array_merge((array)\$_smarty_config, \$this->_conf_obj->get(".$attrs['file'].", ".$attrs['section']."));\n"; $output .= "\$_smarty_config = array_merge((array)\$_smarty_config, \$this->_conf_obj->get(".$attrs['file'].", ".$attrs['section']."));\n";
if ($update_parent) if ($update_parent)
$output .= "\$_smarty_config_parent = array_merge((array)\$_smarty_config_parent, \$this->_conf_obj->get(".$attrs['file'].", ".$attrs['section']."));\n"; $output .= "\$_smarty_config_parent = array_merge((array)\$_smarty_config_parent, \$this->_conf_obj->get(".$attrs['file'].", ".$attrs['section']."));\n";
} }
$output .= '?>'; $output .= '?>';
@@ -382,21 +381,21 @@ class Smarty_Compiler extends Smarty {
$this->_syntax_error("missing 'file' attribute in include tag"); $this->_syntax_error("missing 'file' attribute in include tag");
} }
foreach ($attrs as $arg_name => $arg_value) { foreach ($attrs as $arg_name => $arg_value) {
if ($arg_name == 'file') { if ($arg_name == 'file') {
$include_file = $arg_value; $include_file = $arg_value;
continue; continue;
} }
if (is_bool($arg_value)) if (is_bool($arg_value))
$arg_value = $arg_value ? 'true' : 'false'; $arg_value = $arg_value ? 'true' : 'false';
$arg_list[] = "'$arg_name' => $arg_value"; $arg_list[] = "'$arg_name' => $arg_value";
} }
return "<?php " . return "<?php " .
"\$_smarty_tpl_vars = \$this->_tpl_vars;\n" . "\$_smarty_tpl_vars = \$this->_tpl_vars;\n" .
"\$this->_smarty_include(".$include_file.", array(".implode(',', (array)$arg_list)."), \$_smarty_config);\n" . "\$this->_smarty_include(".$include_file.", array(".implode(',', (array)$arg_list)."), \$_smarty_config);\n" .
"\$this->_tpl_vars = \$_smarty_tpl_vars;\n" . "\$this->_tpl_vars = \$_smarty_tpl_vars;\n" .
"unset(\$_smarty_tpl_vars); ?>"; "unset(\$_smarty_tpl_vars); ?>";
} }
@@ -456,8 +455,8 @@ class Smarty_Compiler extends Smarty {
$output .= "{$section_props}['rownum'] = {$section_props}['index'] + 1;\n"; $output .= "{$section_props}['rownum'] = {$section_props}['index'] + 1;\n";
$output .= "{$section_props}['index_prev'] = {$section_props}['index'] - 1;\n"; $output .= "{$section_props}['index_prev'] = {$section_props}['index'] - 1;\n";
$output .= "{$section_props}['index_next'] = {$section_props}['index'] + 1;\n"; $output .= "{$section_props}['index_next'] = {$section_props}['index'] + 1;\n";
$output .= "{$section_props}['first'] = ({$section_props}['index'] == 0);\n"; $output .= "{$section_props}['first'] = ({$section_props}['index'] == 0);\n";
$output .= "{$section_props}['last'] = ({$section_props}['index'] == {$section_props}['loop']-1);\n"; $output .= "{$section_props}['last'] = ({$section_props}['index'] == {$section_props}['loop']-1);\n";
$output .= "?>"; $output .= "?>";
@@ -485,7 +484,7 @@ class Smarty_Compiler extends Smarty {
$is_arg_stack = array(); $is_arg_stack = array();
for ($i = 0; $i < count($tokens); $i++) { for ($i = 0; $i < count($tokens); $i++) {
$token = &$tokens[$i]; $token = &$tokens[$i];
switch ($token) { switch ($token) {
case 'eq': case 'eq':
@@ -561,14 +560,15 @@ class Smarty_Compiler extends Smarty {
current position for the next iteration. */ current position for the next iteration. */
$i = $is_arg_start; $i = $is_arg_start;
break; break;
default:
if($this->security default:
&& $tokens[$i+1] == '(' if($this->security &&
&& !preg_match("|[^a-zA-Z_-]|",$tokens[$i]) $tokens[$i+1] == '(' &&
&& !in_array($tokens[$i],$this->security_settings["ALLOW_IF_FUNCS"])) { !preg_match("|[^a-zA-Z_]|",$tokens[$i]) &&
$this->_syntax_error("(secure mode) '".$tokens[$i]."' not allowed in if statement"); !in_array($tokens[$i], $this->security_settings['IF_FUNCS'])) {
} $this->_syntax_error("(secure mode) '".$tokens[$i]."' not allowed in if statement");
break; }
break;
} }
} }
@@ -712,11 +712,11 @@ class Smarty_Compiler extends Smarty {
return $attrs; return $attrs;
} }
/*======================================================================*\ /*======================================================================*\
Function: _parse_vars_props Function: _parse_vars_props
Purpose: compile variables and section properties tokens into Purpose: compile variables and section properties tokens into
PHP code PHP code
\*======================================================================*/ \*======================================================================*/
function _parse_vars_props(&$tokens) function _parse_vars_props(&$tokens)
{ {
@@ -752,28 +752,28 @@ class Smarty_Compiler extends Smarty {
\*======================================================================*/ \*======================================================================*/
function _parse_var($var_expr) function _parse_var($var_expr)
{ {
$parts = explode('|', substr($var_expr, 1), 2); $parts = explode('|', substr($var_expr, 1), 2);
$var_ref = $parts[0]; $var_ref = $parts[0];
$modifiers = isset($parts[1]) ? $parts[1] : ''; $modifiers = isset($parts[1]) ? $parts[1] : '';
preg_match_all('!\[\w+(\.\w+)?\]|(->|\.)\w+|^\w+!', $var_ref, $match); preg_match_all('!\[\w+(\.\w+)?\]|(->|\.)\w+|^\w+!', $var_ref, $match);
$indexes = $match[0]; $indexes = $match[0];
$var_name = array_shift($indexes); $var_name = array_shift($indexes);
$output = "\$this->_tpl_vars['$var_name']"; $output = "\$this->_tpl_vars['$var_name']";
foreach ($indexes as $index) { foreach ($indexes as $index) {
if ($index{0} == '[') { if ($index{0} == '[') {
$parts = explode('.', substr($index, 1, -1)); $parts = explode('.', substr($index, 1, -1));
$section = $parts[0]; $section = $parts[0];
$section_prop = isset($parts[1]) ? $parts[1] : 'index'; $section_prop = isset($parts[1]) ? $parts[1] : 'index';
$output .= "[\$this->_sections['$section']['properties']['$section_prop']]"; $output .= "[\$this->_sections['$section']['properties']['$section_prop']]";
} else if ($index{0} == '.') { } else if ($index{0} == '.') {
$output .= "['" . substr($index, 1) . "']"; $output .= "['" . substr($index, 1) . "']";
} else { } else {
$output .= $index; $output .= $index;
} }
} }
$this->_parse_modifiers($output, $modifiers); $this->_parse_modifiers($output, $modifiers);
@@ -788,8 +788,8 @@ class Smarty_Compiler extends Smarty {
function _parse_conf_var($conf_var_expr) function _parse_conf_var($conf_var_expr)
{ {
$parts = explode('|', $conf_var_expr, 2); $parts = explode('|', $conf_var_expr, 2);
$var_ref = $parts[0]; $var_ref = $parts[0];
$modifiers = isset($parts[1]) ? $parts[1] : ''; $modifiers = isset($parts[1]) ? $parts[1] : '';
$var_name = substr($var_ref, 1, -1); $var_name = substr($var_ref, 1, -1);
@@ -808,8 +808,8 @@ class Smarty_Compiler extends Smarty {
function _parse_section_prop($section_prop_expr) function _parse_section_prop($section_prop_expr)
{ {
$parts = explode('|', $section_prop_expr, 2); $parts = explode('|', $section_prop_expr, 2);
$var_ref = $parts[0]; $var_ref = $parts[0];
$modifiers = isset($parts[1]) ? $parts[1] : ''; $modifiers = isset($parts[1]) ? $parts[1] : '';
preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match); preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match);
$section_name = $match[1]; $section_name = $match[1];
@@ -855,13 +855,13 @@ class Smarty_Compiler extends Smarty {
* function name. * function name.
*/ */
if (!isset($mod_func_name)) { if (!isset($mod_func_name)) {
if($this->security && !in_array($modifier_name,$this->security_settings["ALLOW_MODIFIER_FUNCS"])) { if ($this->security && !in_array($modifier_name, $this->security_settings['MODIFIER_FUNCS'])) {
$this->_syntax_error("(secure mode) modifier '$modifier_name' is not allowed", E_USER_WARNING); $this->_syntax_error("(secure mode) modifier '$modifier_name' is not allowed", E_USER_WARNING);
continue; continue;
} else { } else {
$mod_func_name = $modifier_name; $mod_func_name = $modifier_name;
} }
} }
if (!function_exists($mod_func_name)) { if (!function_exists($mod_func_name)) {
$this->_syntax_error("modifier '$modifier_name' is not implemented", E_USER_WARNING); $this->_syntax_error("modifier '$modifier_name' is not implemented", E_USER_WARNING);