From 4396351d75d16e540c5d4835abf5a8b27ef32e8f Mon Sep 17 00:00:00 2001 From: Simon Wisselink Date: Mon, 13 Apr 2020 22:24:29 +0200 Subject: [PATCH] Switched to a more advanced regex to test wheter parameter is a variable (#567) * This appears to fix #453, #498, #499 and possibly more issues. --- change_log.txt | 1 + .../smarty_internal_templatecompilerbase.php | 34 ++++++++++++------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/change_log.txt b/change_log.txt index 10a0169c..082b36fb 100644 --- a/change_log.txt +++ b/change_log.txt @@ -1,4 +1,5 @@ - fix foreachelse on arrayiterators https://github.com/smarty-php/smarty/issues/506 + - fix errors that occured where isset was replaced with null check such as https://github.com/smarty-php/smarty/issues/453 ===== 3.1.34 release ===== 05.11.2019 13.01.2020 diff --git a/libs/sysplugins/smarty_internal_templatecompilerbase.php b/libs/sysplugins/smarty_internal_templatecompilerbase.php index a72f3a4a..7652b70b 100644 --- a/libs/sysplugins/smarty_internal_templatecompilerbase.php +++ b/libs/sysplugins/smarty_internal_templatecompilerbase.php @@ -621,22 +621,18 @@ abstract class Smarty_Internal_TemplateCompilerBase || strcasecmp($name, 'array') === 0 || is_callable($name) ) { $func_name = strtolower($name); - $par = implode(',', $parameter); - $parHasFuction = strpos($par, '(') !== false; + if ($func_name === 'isset') { if (count($parameter) === 0) { $this->trigger_template_error('Illegal number of parameter in "isset()"'); } - if ($parHasFuction) { - $pa = array(); - foreach ($parameter as $p) { - $pa[] = (strpos($p, '(') === false) ? ('isset(' . $p . ')') : ('(' . $p . ' !== null )'); - } - return '(' . implode(' && ', $pa) . ')'; - } else { - $isset_par = str_replace("')->value", "',null,true,false)->value", $par); - } - return $name . '(' . $isset_par . ')'; + + $pa = array(); + foreach ($parameter as $p) { + $pa[] = $this->syntaxMatchesVariable($p) ? 'isset(' . $p . ')' : '(' . $p . ' !== null )'; + } + return '(' . implode(' && ', $pa) . ')'; + } elseif (in_array( $func_name, array( @@ -653,7 +649,7 @@ abstract class Smarty_Internal_TemplateCompilerBase $this->trigger_template_error("Illegal number of parameter in '{$func_name()}'"); } if ($func_name === 'empty') { - if ($parHasFuction && version_compare(PHP_VERSION, '5.5.0', '<')) { + if (!$this->syntaxMatchesVariable($parameter[0]) && version_compare(PHP_VERSION, '5.5.0', '<')) { return '(' . $parameter[ 0 ] . ' === false )'; } else { return $func_name . '(' . @@ -671,6 +667,18 @@ abstract class Smarty_Internal_TemplateCompilerBase } } + /** + * Determines whether the passed string represents a valid (PHP) variable. + * This is important, because `isset()` only works on variables and `empty()` can only be passed + * a variable prior to php5.5 + * @param $string + * @return bool + */ + private function syntaxMatchesVariable($string) { + static $regex_pattern = '/^\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*((->)[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*|\[.*]*\])*$/'; + return 1 === preg_match($regex_pattern, trim($string)); + } + /** * This method is called from parser to process a text content section * - remove text from inheritance child templates as they may generate output