From dda97e28c3cb621c953b85292402b18c8fe8fcbd Mon Sep 17 00:00:00 2001 From: Seamus Lee Date: Sat, 12 Aug 2017 19:38:03 +1000 Subject: [PATCH 1/3] Upgrade Smarty to 2.6.30 --- Smarty/Config_File.class.php | 4 +- Smarty/Smarty.class.php | 55 +++-------- Smarty/Smarty_Compiler.class.php | 56 +++++------ .../core.assemble_plugin_filepath.php | 8 +- Smarty/plugins/function.math.php | 99 +++++++++++-------- 5 files changed, 104 insertions(+), 118 deletions(-) diff --git a/Smarty/Config_File.class.php b/Smarty/Config_File.class.php index c25f2a0ea..6d8c2987f 100644 --- a/Smarty/Config_File.class.php +++ b/Smarty/Config_File.class.php @@ -29,7 +29,7 @@ * @package Smarty */ -/* $Id: Config_File.class.php 3149 2009-05-23 20:59:25Z monte.ohrt $ */ +/* $Id$ */ /** * Config file reading class @@ -73,7 +73,7 @@ class Config_File { * * @param string $config_path (optional) path to the config files */ - function Config_File($config_path = NULL) + public function __construct($config_path = NULL) { if (isset($config_path)) $this->set_path($config_path); diff --git a/Smarty/Smarty.class.php b/Smarty/Smarty.class.php index dac932962..41d53706f 100644 --- a/Smarty/Smarty.class.php +++ b/Smarty/Smarty.class.php @@ -27,10 +27,10 @@ * @author Monte Ohrt * @author Andrei Zmievski * @package Smarty - * @version 2.6.27 + * @version 2.6.30 */ -/* $Id: Smarty.class.php 4660 2012-09-24 20:05:15Z uwe.tews@googlemail.com $ */ +/* $Id$ */ /** * DIR_SEP isn't used anymore, but third party apps might @@ -465,7 +465,7 @@ class Smarty * * @var string */ - var $_version = '2.6.27'; + var $_version = '2.6.30'; /** * current template inclusion depth @@ -562,11 +562,17 @@ class Smarty */ var $_cache_including = false; + /** + * plugin filepath cache + * + * @var array + */ + var $_filepaths_cache = array(); /**#@-*/ /** * The class constructor. */ - function Smarty() + public function __construct() { $this->assign('SCRIPT_NAME', isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME'] : @$GLOBALS['HTTP_SERVER_VARS']['SCRIPT_NAME']); @@ -1511,45 +1517,8 @@ function _compile_source($resource_name, &$source_content, &$compiled_content, $ */ function _get_compile_path($resource_name) { - $compilePath = $this->_get_auto_filename( $this->compile_dir, - $resource_name, - $this->_compile_id ); - $compilePath .= '.php'; - - //for 'string:' resource smarty might going to fail to create - //compile file, so make sure we should have valid path, CRM-5890 - $matches = array( ); - if ( preg_match( '/^(\s+)?string:/', $resource_name, $matches ) ) { - if ( !$this->validateCompilePath( $compilePath ) ) { - $compilePath = $this->_get_auto_filename( $this->compile_dir, - time().rand(), - $this->_compile_id ); - $compilePath .= '.php'; - } - } - - return $compilePath; - } - - /** - * do check can smarty create a file w/ given path. - */ - function validateCompilePath( $compilePath ) { - //first check for directory. - $dirname = dirname( $compilePath ); - if ( !is_dir( $dirname ) ) { - require_once(SMARTY_CORE_DIR . 'core.create_dir_structure.php'); - smarty_core_create_dir_structure( array('dir' => $dirname ), $this ); - } - - $isValid = false; - if ( $fd = @fopen( $compilePath, 'wb') ) { - $isValid = true; - @fclose( $fd ); - @unlink($compilePath); - } - - return $isValid; + return $this->_get_auto_filename($this->compile_dir, $resource_name, + $this->_compile_id) . '.php'; } /** diff --git a/Smarty/Smarty_Compiler.class.php b/Smarty/Smarty_Compiler.class.php index f455802f2..006021505 100644 --- a/Smarty/Smarty_Compiler.class.php +++ b/Smarty/Smarty_Compiler.class.php @@ -26,7 +26,7 @@ * @package Smarty */ -/* $Id: Smarty_Compiler.class.php 3163 2009-06-17 14:39:24Z monte.ohrt $ */ +/* $Id$ */ /** * Template compiling class @@ -78,7 +78,7 @@ class Smarty_Compiler extends Smarty { /** * The class constructor. */ - function Smarty_Compiler() + public function __construct() { // matches double quoted strings: // "foobar" @@ -162,7 +162,7 @@ function Smarty_Compiler() . '(?:\s*,\s*' . $this->_obj_single_param_regexp . ')*)?\)'; $this->_obj_start_regexp = '(?:' . $this->_dvar_regexp . '(?:' . $this->_obj_ext_regexp . ')+)'; $this->_obj_call_regexp = '(?:' . $this->_obj_start_regexp . '(?:' . $this->_obj_params_regexp . ')?(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?)'; - + // matches valid modifier syntax: // |foo // |@foo @@ -304,7 +304,7 @@ function _compile_file($resource_name, $source_content, &$compiled_content) } } } - + /* Compile the template tags into PHP code. */ $compiled_tags = array(); for ($i = 0, $for_max = count($template_tags); $i < $for_max; $i++) { @@ -333,7 +333,7 @@ function _compile_file($resource_name, $source_content, &$compiled_content) for ($j = $i + 1; $j < $for_max; $j++) { /* remove leading and trailing whitespaces of each line */ $text_blocks[$j] = preg_replace('![\t ]*[\r\n]+[\t ]*!', '', $text_blocks[$j]); - if ($compiled_tags[$j] == '{/strip}') { + if ($compiled_tags[$j] == '{/strip}') { /* remove trailing whitespaces from the last text_block */ $text_blocks[$j] = rtrim($text_blocks[$j]); } @@ -349,9 +349,9 @@ function _compile_file($resource_name, $source_content, &$compiled_content) } } $compiled_content = ''; - + $tag_guard = '%%%SMARTYOTG' . md5(uniqid(rand(), true)) . '%%%'; - + /* Interleave the compiled contents and text blocks to get the final result. */ for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) { if ($compiled_tags[$i] == '') { @@ -361,7 +361,7 @@ function _compile_file($resource_name, $source_content, &$compiled_content) // replace legit PHP tags with placeholder $text_blocks[$i] = str_replace('\n", $compiled_content); // recover legit tags - $compiled_content = str_replace($tag_guard, '_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '|\/?' . $this->_reg_obj_regexp . '|\/?' . $this->_func_regexp . ')(' . $this->_mod_regexp . '*)) @@ -445,7 +445,7 @@ function _compile_tag($template_tag) ~xs', $template_tag, $match)) { $this->_syntax_error("unrecognized tag: $template_tag", E_USER_ERROR, __FILE__, __LINE__); } - + $tag_command = $match[1]; $tag_modifier = isset($match[2]) ? $match[2] : null; $tag_args = isset($match[3]) ? $match[3] : null; @@ -585,7 +585,7 @@ function _compile_tag($template_tag) } else if ($this->_compile_block_tag($tag_command, $tag_args, $tag_modifier, $output)) { return $output; } else if ($this->_compile_custom_tag($tag_command, $tag_args, $tag_modifier, $output)) { - return $output; + return $output; } else { $this->_syntax_error("unrecognized tag '$tag_command'", E_USER_ERROR, __FILE__, __LINE__); } @@ -936,7 +936,7 @@ function _compile_insert_tag($tag_args) if (empty($name)) { return $this->_syntax_error("missing insert name", E_USER_ERROR, __FILE__, __LINE__); } - + if (!preg_match('~^\w+$~', $name)) { return $this->_syntax_error("'insert: 'name' must be an insert function name", E_USER_ERROR, __FILE__, __LINE__); } @@ -1225,7 +1225,7 @@ function _compile_capture_tag($start, $tag_args = '') $buffer = isset($attrs['name']) ? $attrs['name'] : "'default'"; $assign = isset($attrs['assign']) ? $attrs['assign'] : null; $append = isset($attrs['append']) ? $attrs['append'] : null; - + $output = ""; $this->_capture_stack[] = array($buffer, $assign, $append); } else { @@ -1266,11 +1266,11 @@ function _compile_if_tag($tag_args, $elseif = false) if(empty($tokens)) { $_error_msg = $elseif ? "'elseif'" : "'if'"; - $_error_msg .= ' statement requires arguments'; + $_error_msg .= ' statement requires arguments'; $this->_syntax_error($_error_msg, E_USER_ERROR, __FILE__, __LINE__); } - - + + // make sure we have balanced parenthesis $token_count = array_count_values($tokens); if(isset($token_count['(']) && $token_count['('] != $token_count[')']) { @@ -1368,8 +1368,8 @@ function _compile_if_tag($tag_args, $elseif = false) if ($is_arg_start != 0) { if (preg_match('~^' . $this->_func_regexp . '$~', $tokens[$is_arg_start-1])) { $is_arg_start--; - } - } + } + } } else $is_arg_start = $i-1; /* Construct the argument for 'is' expression, so it knows @@ -1400,7 +1400,7 @@ function _compile_if_tag($tag_args, $elseif = false) } } elseif(preg_match('~^' . $this->_var_regexp . '$~', $token) && (strpos('+-*/^%&|', substr($token, -1)) === false) && isset($tokens[$i+1]) && $tokens[$i+1] == '(') { // variable function call - $this->_syntax_error("variable function call '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__); + $this->_syntax_error("variable function call '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__); } elseif(preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)$~', $token)) { // object or variable $token = $this->_parse_var_props($token); @@ -1753,12 +1753,12 @@ function _parse_var($var_expr) $_var_ref = $var_expr; else $_var_ref = substr($var_expr, 1); - + if(!$_has_math) { - + // get [foo] and .foo and ->foo and (...) pieces preg_match_all('~(?:^\w+)|' . $this->_obj_params_regexp . '|(?:' . $this->_var_bracket_regexp . ')|->\$?\w+|\.\$?\w+|\S+~', $_var_ref, $match); - + $_indexes = $match[0]; $_var_name = array_shift($_indexes); @@ -2018,7 +2018,7 @@ function _compile_smarty_ref(&$indexes) array_shift($indexes); $compiled_ref = "(\$this->_foreach[$_var]['iteration']-1)"; break; - + case 'first': array_shift($indexes); $compiled_ref = "(\$this->_foreach[$_var]['iteration'] <= 1)"; @@ -2028,12 +2028,12 @@ function _compile_smarty_ref(&$indexes) array_shift($indexes); $compiled_ref = "(\$this->_foreach[$_var]['iteration'] == \$this->_foreach[$_var]['total'])"; break; - + case 'show': array_shift($indexes); $compiled_ref = "(\$this->_foreach[$_var]['total'] > 0)"; break; - + default: unset($_max_index); $compiled_ref = "\$this->_foreach[$_var]"; @@ -2159,7 +2159,7 @@ function _compile_smarty_ref(&$indexes) case 'rdelim': $compiled_ref = "'$this->right_delimiter'"; break; - + default: $this->_syntax_error('$smarty.' . $_ref . ' is an unknown reference', E_USER_ERROR, __FILE__, __LINE__); break; diff --git a/Smarty/internals/core.assemble_plugin_filepath.php b/Smarty/internals/core.assemble_plugin_filepath.php index 690d3ddbc..22c02483f 100644 --- a/Smarty/internals/core.assemble_plugin_filepath.php +++ b/Smarty/internals/core.assemble_plugin_filepath.php @@ -14,11 +14,9 @@ */ function smarty_core_assemble_plugin_filepath($params, &$smarty) { - static $_filepaths_cache = array(); - $_plugin_filename = $params['type'] . '.' . $params['name'] . '.php'; - if (isset($_filepaths_cache[$_plugin_filename])) { - return $_filepaths_cache[$_plugin_filename]; + if (isset($smarty->_filepaths_cache[$_plugin_filename])) { + return $smarty->_filepaths_cache[$_plugin_filename]; } $_return = false; @@ -58,7 +56,7 @@ function smarty_core_assemble_plugin_filepath($params, &$smarty) } } } - $_filepaths_cache[$_plugin_filename] = $_return; + $smarty->_filepaths_cache[$_plugin_filename] = $_return; return $_return; } diff --git a/Smarty/plugins/function.math.php b/Smarty/plugins/function.math.php index 6575e0600..655fe728d 100644 --- a/Smarty/plugins/function.math.php +++ b/Smarty/plugins/function.math.php @@ -1,85 +1,104 @@ * Name: math
- * Purpose: handle math computations in template
- * @link http://smarty.php.net/manual/en/language.function.math.php {math} - * (Smarty online manual) + * Purpose: handle math computations in template + * + * @link http://www.smarty.net/manual/en/language.function.math.php {math} + * (Smarty online manual) * @author Monte Ohrt - * @param array - * @param Smarty - * @return string + * + * @param array $params parameters + * @param Smarty_Internal_Template $template template object + * + * @return string|null */ -function smarty_function_math($params, &$smarty) +function smarty_function_math($params, $template) { + static $_allowed_funcs = + array('int' => true, 'abs' => true, 'ceil' => true, 'cos' => true, 'exp' => true, 'floor' => true, + 'log' => true, 'log10' => true, 'max' => true, 'min' => true, 'pi' => true, 'pow' => true, 'rand' => true, + 'round' => true, 'sin' => true, 'sqrt' => true, 'srand' => true, 'tan' => true); // be sure equation parameter is present - if (empty($params['equation'])) { - $smarty->trigger_error("math: missing equation parameter"); + if (empty($params[ 'equation' ])) { + trigger_error("math: missing equation parameter", E_USER_WARNING); + return; } - // strip out backticks, not necessary for math - $equation = str_replace('`','',$params['equation']); + $equation = $params[ 'equation' ]; // make sure parenthesis are balanced - if (substr_count($equation,"(") != substr_count($equation,")")) { - $smarty->trigger_error("math: unbalanced parenthesis"); + if (substr_count($equation, "(") != substr_count($equation, ")")) { + trigger_error("math: unbalanced parenthesis", E_USER_WARNING); + + return; + } + + // disallow backticks + if (strpos($equation, '`') !== false) { + trigger_error("math: backtick character not allowed in equation", E_USER_WARNING); + + return; + } + + // also disallow dollar signs + if (strpos($equation, '$') !== false) { + trigger_error("math: dollar signs not allowed in equation", E_USER_WARNING); + return; } // match all vars in equation, make sure all are passed - preg_match_all("!(?:0x[a-fA-F0-9]+)|([a-zA-Z][a-zA-Z0-9_]*)!",$equation, $match); - $allowed_funcs = array('int','abs','ceil','cos','exp','floor','log','log10', - 'max','min','pi','pow','rand','round','sin','sqrt','srand','tan'); - - foreach($match[1] as $curr_var) { - if ($curr_var && !in_array($curr_var, array_keys($params)) && !in_array($curr_var, $allowed_funcs)) { - $smarty->trigger_error("math: function call $curr_var not allowed"); + preg_match_all('!(?:0x[a-fA-F0-9]+)|([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)!', $equation, $match); + + foreach ($match[ 1 ] as $curr_var) { + if ($curr_var && !isset($params[ $curr_var ]) && !isset($_allowed_funcs[ $curr_var ])) { + trigger_error("math: function call $curr_var not allowed", E_USER_WARNING); + return; } } - foreach($params as $key => $val) { + foreach ($params as $key => $val) { if ($key != "equation" && $key != "format" && $key != "assign") { // make sure value is not empty - if (strlen($val)==0) { - $smarty->trigger_error("math: parameter $key is empty"); + if (strlen($val) == 0) { + trigger_error("math: parameter $key is empty", E_USER_WARNING); + return; } if (!is_numeric($val)) { - $smarty->trigger_error("math: parameter $key: is not numeric"); + trigger_error("math: parameter $key: is not numeric", E_USER_WARNING); + return; } $equation = preg_replace("/\b$key\b/", " \$params['$key'] ", $equation); } } + $smarty_math_result = null; + eval("\$smarty_math_result = " . $equation . ";"); - eval("\$smarty_math_result = ".$equation.";"); - - if (empty($params['format'])) { - if (empty($params['assign'])) { + if (empty($params[ 'format' ])) { + if (empty($params[ 'assign' ])) { return $smarty_math_result; } else { - $smarty->assign($params['assign'],$smarty_math_result); + $template->assign($params[ 'assign' ], $smarty_math_result); } } else { - if (empty($params['assign'])){ - printf($params['format'],$smarty_math_result); + if (empty($params[ 'assign' ])) { + printf($params[ 'format' ], $smarty_math_result); } else { - $smarty->assign($params['assign'],sprintf($params['format'],$smarty_math_result)); + $template->assign($params[ 'assign' ], sprintf($params[ 'format' ], $smarty_math_result)); } } } - -/* vim: set expandtab: */ - -?> \ No newline at end of file From 9afb0fe5a50fe02ddb1bbd958161ee85fa5c9e2b Mon Sep 17 00:00:00 2001 From: Seamus Lee Date: Sat, 12 Aug 2017 19:45:34 +1000 Subject: [PATCH 2/3] Re-apply fix for CRM-5890 --- Smarty/Config_File.class.php | 4 +-- Smarty/Smarty.class.php | 37 ++++++++++++++++++++++- Smarty/Smarty_Compiler.class.php | 52 ++++++++++++++++---------------- Smarty/plugins/function.math.php | 31 +++++++++---------- 4 files changed, 79 insertions(+), 45 deletions(-) diff --git a/Smarty/Config_File.class.php b/Smarty/Config_File.class.php index 6d8c2987f..491fa8408 100644 --- a/Smarty/Config_File.class.php +++ b/Smarty/Config_File.class.php @@ -19,7 +19,7 @@ * * For questions, help, comments, discussion, etc., please join the * Smarty mailing list. Send a blank e-mail to - * smarty-discussion-subscribe@googlegroups.com + * smarty-discussion-subscribe@googlegroups.com * * @link http://www.smarty.net/ * @version 2.6.25-dev @@ -301,7 +301,7 @@ function parse_contents($contents) $vars = array(); continue; } - } else { + } else { $section_name = $match[1]; } if (!isset($config_data['sections'][$section_name])) diff --git a/Smarty/Smarty.class.php b/Smarty/Smarty.class.php index 41d53706f..8890c4528 100644 --- a/Smarty/Smarty.class.php +++ b/Smarty/Smarty.class.php @@ -1517,8 +1517,43 @@ function _compile_source($resource_name, &$source_content, &$compiled_content, $ */ function _get_compile_path($resource_name) { - return $this->_get_auto_filename($this->compile_dir, $resource_name, + $compilePath = $this->_get_auto_filename($this->compile_dir, $resource_name, $this->_compile_id) . '.php'; + + //for 'string:' resource smarty might going to fail to create + //compile file, so make sure we should have valid path, CRM-5890 + $matches = array( ); + if ( preg_match( '/^(\s+)?string:/', $resource_name, $matches ) ) { + if ( !$this->validateCompilePath( $compilePath ) ) { + $compilePath = $this->_get_auto_filename( $this->compile_dir, + time().rand(), + $this->_compile_id ); + $compilePath .= '.php'; + } + } + + return $compilePath; + } + + /** + * do check can smarty create a file w/ given path. + */ + function validateCompilePath( $compilePath ) { + //first check for directory. + $dirname = dirname( $compilePath ); + if ( !is_dir( $dirname ) ) { + require_once(SMARTY_CORE_DIR . 'core.create_dir_structure.php'); + smarty_core_create_dir_structure( array('dir' => $dirname ), $this ); + } + + $isValid = FALSE; + if ( $fd = @fopen( $compilePath, 'wb') ) { + $isValid = TRUE; + @fclose( $fd ); + @unlink($compilePath); + } + + return $isValid; } /** diff --git a/Smarty/Smarty_Compiler.class.php b/Smarty/Smarty_Compiler.class.php index 006021505..8eaf75823 100644 --- a/Smarty/Smarty_Compiler.class.php +++ b/Smarty/Smarty_Compiler.class.php @@ -162,7 +162,7 @@ public function __construct() . '(?:\s*,\s*' . $this->_obj_single_param_regexp . ')*)?\)'; $this->_obj_start_regexp = '(?:' . $this->_dvar_regexp . '(?:' . $this->_obj_ext_regexp . ')+)'; $this->_obj_call_regexp = '(?:' . $this->_obj_start_regexp . '(?:' . $this->_obj_params_regexp . ')?(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?)'; - + // matches valid modifier syntax: // |foo // |@foo @@ -304,7 +304,7 @@ function _compile_file($resource_name, $source_content, &$compiled_content) } } } - + /* Compile the template tags into PHP code. */ $compiled_tags = array(); for ($i = 0, $for_max = count($template_tags); $i < $for_max; $i++) { @@ -333,7 +333,7 @@ function _compile_file($resource_name, $source_content, &$compiled_content) for ($j = $i + 1; $j < $for_max; $j++) { /* remove leading and trailing whitespaces of each line */ $text_blocks[$j] = preg_replace('![\t ]*[\r\n]+[\t ]*!', '', $text_blocks[$j]); - if ($compiled_tags[$j] == '{/strip}') { + if ($compiled_tags[$j] == '{/strip}') { /* remove trailing whitespaces from the last text_block */ $text_blocks[$j] = rtrim($text_blocks[$j]); } @@ -349,9 +349,9 @@ function _compile_file($resource_name, $source_content, &$compiled_content) } } $compiled_content = ''; - + $tag_guard = '%%%SMARTYOTG' . md5(uniqid(rand(), true)) . '%%%'; - + /* Interleave the compiled contents and text blocks to get the final result. */ for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) { if ($compiled_tags[$i] == '') { @@ -361,7 +361,7 @@ function _compile_file($resource_name, $source_content, &$compiled_content) // replace legit PHP tags with placeholder $text_blocks[$i] = str_replace('\n", $compiled_content); // recover legit tags - $compiled_content = str_replace($tag_guard, '_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '|\/?' . $this->_reg_obj_regexp . '|\/?' . $this->_func_regexp . ')(' . $this->_mod_regexp . '*)) @@ -445,7 +445,7 @@ function _compile_tag($template_tag) ~xs', $template_tag, $match)) { $this->_syntax_error("unrecognized tag: $template_tag", E_USER_ERROR, __FILE__, __LINE__); } - + $tag_command = $match[1]; $tag_modifier = isset($match[2]) ? $match[2] : null; $tag_args = isset($match[3]) ? $match[3] : null; @@ -585,7 +585,7 @@ function _compile_tag($template_tag) } else if ($this->_compile_block_tag($tag_command, $tag_args, $tag_modifier, $output)) { return $output; } else if ($this->_compile_custom_tag($tag_command, $tag_args, $tag_modifier, $output)) { - return $output; + return $output; } else { $this->_syntax_error("unrecognized tag '$tag_command'", E_USER_ERROR, __FILE__, __LINE__); } @@ -936,7 +936,7 @@ function _compile_insert_tag($tag_args) if (empty($name)) { return $this->_syntax_error("missing insert name", E_USER_ERROR, __FILE__, __LINE__); } - + if (!preg_match('~^\w+$~', $name)) { return $this->_syntax_error("'insert: 'name' must be an insert function name", E_USER_ERROR, __FILE__, __LINE__); } @@ -1225,7 +1225,7 @@ function _compile_capture_tag($start, $tag_args = '') $buffer = isset($attrs['name']) ? $attrs['name'] : "'default'"; $assign = isset($attrs['assign']) ? $attrs['assign'] : null; $append = isset($attrs['append']) ? $attrs['append'] : null; - + $output = ""; $this->_capture_stack[] = array($buffer, $assign, $append); } else { @@ -1266,11 +1266,11 @@ function _compile_if_tag($tag_args, $elseif = false) if(empty($tokens)) { $_error_msg = $elseif ? "'elseif'" : "'if'"; - $_error_msg .= ' statement requires arguments'; + $_error_msg .= ' statement requires arguments'; $this->_syntax_error($_error_msg, E_USER_ERROR, __FILE__, __LINE__); } - - + + // make sure we have balanced parenthesis $token_count = array_count_values($tokens); if(isset($token_count['(']) && $token_count['('] != $token_count[')']) { @@ -1368,8 +1368,8 @@ function _compile_if_tag($tag_args, $elseif = false) if ($is_arg_start != 0) { if (preg_match('~^' . $this->_func_regexp . '$~', $tokens[$is_arg_start-1])) { $is_arg_start--; - } - } + } + } } else $is_arg_start = $i-1; /* Construct the argument for 'is' expression, so it knows @@ -1400,7 +1400,7 @@ function _compile_if_tag($tag_args, $elseif = false) } } elseif(preg_match('~^' . $this->_var_regexp . '$~', $token) && (strpos('+-*/^%&|', substr($token, -1)) === false) && isset($tokens[$i+1]) && $tokens[$i+1] == '(') { // variable function call - $this->_syntax_error("variable function call '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__); + $this->_syntax_error("variable function call '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__); } elseif(preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)$~', $token)) { // object or variable $token = $this->_parse_var_props($token); @@ -1753,12 +1753,12 @@ function _parse_var($var_expr) $_var_ref = $var_expr; else $_var_ref = substr($var_expr, 1); - + if(!$_has_math) { - + // get [foo] and .foo and ->foo and (...) pieces preg_match_all('~(?:^\w+)|' . $this->_obj_params_regexp . '|(?:' . $this->_var_bracket_regexp . ')|->\$?\w+|\.\$?\w+|\S+~', $_var_ref, $match); - + $_indexes = $match[0]; $_var_name = array_shift($_indexes); @@ -2018,7 +2018,7 @@ function _compile_smarty_ref(&$indexes) array_shift($indexes); $compiled_ref = "(\$this->_foreach[$_var]['iteration']-1)"; break; - + case 'first': array_shift($indexes); $compiled_ref = "(\$this->_foreach[$_var]['iteration'] <= 1)"; @@ -2028,12 +2028,12 @@ function _compile_smarty_ref(&$indexes) array_shift($indexes); $compiled_ref = "(\$this->_foreach[$_var]['iteration'] == \$this->_foreach[$_var]['total'])"; break; - + case 'show': array_shift($indexes); $compiled_ref = "(\$this->_foreach[$_var]['total'] > 0)"; break; - + default: unset($_max_index); $compiled_ref = "\$this->_foreach[$_var]"; @@ -2159,7 +2159,7 @@ function _compile_smarty_ref(&$indexes) case 'rdelim': $compiled_ref = "'$this->right_delimiter'"; break; - + default: $this->_syntax_error('$smarty.' . $_ref . ' is an unknown reference', E_USER_ERROR, __FILE__, __LINE__); break; diff --git a/Smarty/plugins/function.math.php b/Smarty/plugins/function.math.php index 655fe728d..9fc52e1a5 100644 --- a/Smarty/plugins/function.math.php +++ b/Smarty/plugins/function.math.php @@ -24,18 +24,17 @@ */ function smarty_function_math($params, $template) { - static $_allowed_funcs = - array('int' => true, 'abs' => true, 'ceil' => true, 'cos' => true, 'exp' => true, 'floor' => true, - 'log' => true, 'log10' => true, 'max' => true, 'min' => true, 'pi' => true, 'pow' => true, 'rand' => true, - 'round' => true, 'sin' => true, 'sqrt' => true, 'srand' => true, 'tan' => true); + static $_allowed_funcs = array('int' => true, 'abs' => true, 'ceil' => true, 'cos' => true, 'exp' => true, 'floor' => true, + 'log' => true, 'log10' => true, 'max' => true, 'min' => true, 'pi' => true, 'pow' => true, 'rand' => true, + 'round' => true, 'sin' => true, 'sqrt' => true, 'srand' => true, 'tan' => true); // be sure equation parameter is present - if (empty($params[ 'equation' ])) { + if (empty($params['equation'])) { trigger_error("math: missing equation parameter", E_USER_WARNING); return; } - $equation = $params[ 'equation' ]; + $equation = $params['equation']; // make sure parenthesis are balanced if (substr_count($equation, "(") != substr_count($equation, ")")) { @@ -45,14 +44,14 @@ function smarty_function_math($params, $template) } // disallow backticks - if (strpos($equation, '`') !== false) { + if (strpos($equation, '`') !== FALSE) { trigger_error("math: backtick character not allowed in equation", E_USER_WARNING); return; } // also disallow dollar signs - if (strpos($equation, '$') !== false) { + if (strpos($equation, '$') !== FALSE) { trigger_error("math: dollar signs not allowed in equation", E_USER_WARNING); return; @@ -61,8 +60,8 @@ function smarty_function_math($params, $template) // match all vars in equation, make sure all are passed preg_match_all('!(?:0x[a-fA-F0-9]+)|([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)!', $equation, $match); - foreach ($match[ 1 ] as $curr_var) { - if ($curr_var && !isset($params[ $curr_var ]) && !isset($_allowed_funcs[ $curr_var ])) { + foreach ($match[1] as $curr_var) { + if ($curr_var && !isset($params[$curr_var]) && !isset($_allowed_funcs[$curr_var])) { trigger_error("math: function call $curr_var not allowed", E_USER_WARNING); return; @@ -88,17 +87,17 @@ function smarty_function_math($params, $template) $smarty_math_result = null; eval("\$smarty_math_result = " . $equation . ";"); - if (empty($params[ 'format' ])) { - if (empty($params[ 'assign' ])) { + if (empty($params['format'])) { + if (empty($params['assign'])) { return $smarty_math_result; } else { - $template->assign($params[ 'assign' ], $smarty_math_result); + $template->assign($params['assign'], $smarty_math_result); } } else { - if (empty($params[ 'assign' ])) { - printf($params[ 'format' ], $smarty_math_result); + if (empty($params['assign'])) { + printf($params['format'], $smarty_math_result); } else { - $template->assign($params[ 'assign' ], sprintf($params[ 'format' ], $smarty_math_result)); + $template->assign($params['assign'], sprintf($params['format'], $smarty_math_result)); } } } From 825d8f64d731f9a768d3be628c00efff59780369 Mon Sep 17 00:00:00 2001 From: Seamus Lee Date: Wed, 20 Sep 2017 07:20:33 +1000 Subject: [PATCH 3/3] Port commit 5fb8387 from Smarty Repo fixing a bad backport --- Smarty/plugins/function.math.php | 36 ++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/Smarty/plugins/function.math.php b/Smarty/plugins/function.math.php index 9fc52e1a5..506c050e8 100644 --- a/Smarty/plugins/function.math.php +++ b/Smarty/plugins/function.math.php @@ -18,11 +18,11 @@ * @author Monte Ohrt * * @param array $params parameters - * @param Smarty_Internal_Template $template template object + * @param Smarty * * @return string|null */ -function smarty_function_math($params, $template) +function smarty_function_math($params, &$smarty) { static $_allowed_funcs = array('int' => true, 'abs' => true, 'ceil' => true, 'cos' => true, 'exp' => true, 'floor' => true, 'log' => true, 'log10' => true, 'max' => true, 'min' => true, 'pi' => true, 'pow' => true, 'rand' => true, @@ -57,12 +57,27 @@ function smarty_function_math($params, $template) return; } + foreach ($params as $key => $val) { + if ($key != "equation" && $key != "format" && $key != "assign") { + // make sure value is not empty + if (strlen($val) == 0) { + trigger_error("math: parameter '{$key}' is empty", E_USER_WARNING); + + return; + } + if (!is_numeric($val)) { + trigger_error("math: parameter '{$key}' is not numeric", E_USER_WARNING); + + return; + } + } + } // match all vars in equation, make sure all are passed preg_match_all('!(?:0x[a-fA-F0-9]+)|([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)!', $equation, $match); foreach ($match[1] as $curr_var) { if ($curr_var && !isset($params[$curr_var]) && !isset($_allowed_funcs[$curr_var])) { - trigger_error("math: function call $curr_var not allowed", E_USER_WARNING); + trigger_error("math: function call '{$curr_var}' not allowed, or missing parameter '{$curr_var}'", E_USER_WARNING); return; } @@ -70,17 +85,6 @@ function smarty_function_math($params, $template) foreach ($params as $key => $val) { if ($key != "equation" && $key != "format" && $key != "assign") { - // make sure value is not empty - if (strlen($val) == 0) { - trigger_error("math: parameter $key is empty", E_USER_WARNING); - - return; - } - if (!is_numeric($val)) { - trigger_error("math: parameter $key: is not numeric", E_USER_WARNING); - - return; - } $equation = preg_replace("/\b$key\b/", " \$params['$key'] ", $equation); } } @@ -91,13 +95,13 @@ function smarty_function_math($params, $template) if (empty($params['assign'])) { return $smarty_math_result; } else { - $template->assign($params['assign'], $smarty_math_result); + $smarty->assign($params['assign'], $smarty_math_result); } } else { if (empty($params['assign'])) { printf($params['format'], $smarty_math_result); } else { - $template->assign($params['assign'], sprintf($params['format'], $smarty_math_result)); + $smarty->assign($params['assign'], sprintf($params['format'], $smarty_math_result)); } } }