Moin Mike, [ Mike Gabriel, 2020-12-18 ] > I looked into this today and failed to get the issue fixed. > > I tried updating smarty-lexer to upstream's Git master and rebuilt smarty3 > 3.1.36. Without success... > > So, I filed an upstream report on this and hope for feedback from Uwe... > https://github.com/smarty-php/smarty/issues/621
This might rather be an issue concerning oldish code in GOsa and
slbackup-php than a Smarty bug. At least it seems to be unrelated to
internal parsetree code...
After digging into this a bit (w/o having a real clue about PHP and
Smarty), I noticed that it is sufficient to replace one file to make
both Gosa and slbackup-php work; see the comment about variables prior
to PHP 5.5:
diff -u a/smarty_internal_templatecompilerbase.php
b/smarty_internal_templatecompilerbase.php
--- a/smarty_internal_templatecompilerbase.php 2018-08-31 00:00:00.000000000
+0200
+++ b/smarty_internal_templatecompilerbase.php 2020-04-14 00:00:00.000000000
+0200
@@ -621,22 +621,18 @@
|| 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 @@
$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,74 +667,82 @@
}
}
+ /**
+ * 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
+ * This method is called from parser to process a text content section if
strip is enabled
* - remove text from inheritance child templates as they may generate
output
- * - strip text if strip is enabled
*
* @param string $text
*
- * @return null|\Smarty_Internal_ParseTree_Text
+ * @return string
*/
public function processText($text)
{
- if ((string)$text != '') {
- $store = array();
- $_store = 0;
- if ($this->parser->strip) {
- if (strpos($text, '<') !== false) {
- // capture html elements not to be messed with
- $_offset = 0;
- if (preg_match_all(
-
'#(<script[^>]*>.*?</script[^>]*>)|(<textarea[^>]*>.*?</textarea[^>]*>)|(<pre[^>]*>.*?</pre[^>]*>)#is',
- $text,
- $matches,
- PREG_OFFSET_CAPTURE | PREG_SET_ORDER
- )
- ) {
- foreach ($matches as $match) {
- $store[] = $match[ 0 ][ 0 ];
- $_length = strlen($match[ 0 ][ 0 ]);
- $replace = '@!@SMARTY:' . $_store . ':SMARTY@!@';
- $text = substr_replace($text, $replace, $match[ 0
][ 1 ] - $_offset, $_length);
- $_offset += $_length - strlen($replace);
- $_store++;
- }
- }
- $expressions = array(// replace multiple spaces between
tags by a single space
-
'#(:SMARTY@!@|>)[\040\011]+(?=@!@SMARTY:|<)#s' =>
'\1 \2',
- // remove newline between tags
-
'#(:SMARTY@!@|>)[\040\011]*[\n]\s*(?=@!@SMARTY:|<)#s' =>
'\1\2',
- // remove multiple spaces between
attributes (but not in attribute values!)
-
'#(([a-z0-9]\s*=\s*("[^"]*?")|(\'[^\']*?\'))|<[a-z0-9_]+)\s+([a-z/>])#is' =>
'\1 \5',
- '#>[\040\011]+$#Ss'
=> '> ',
- '#>[\040\011]*[\n]\s*$#Ss'
=> '>',
- $this->stripRegEx
=> '',
- );
- $text = preg_replace(array_keys($expressions),
array_values($expressions), $text);
- $_offset = 0;
- if (preg_match_all(
- '#@!@SMARTY:([0-9]+):SMARTY@!@#is',
- $text,
- $matches,
- PREG_OFFSET_CAPTURE | PREG_SET_ORDER
- )
- ) {
- foreach ($matches as $match) {
- $_length = strlen($match[ 0 ][ 0 ]);
- $replace = $store[ $match[ 1 ][ 0 ] ];
- $text = substr_replace($text, $replace, $match[ 0
][ 1 ] + $_offset, $_length);
- $_offset += strlen($replace) - $_length;
- $_store++;
- }
- }
- } else {
- $text = preg_replace($this->stripRegEx, '', $text);
- }
+
+ if (strpos($text, '<') === false) {
+ return preg_replace($this->stripRegEx, '', $text);
+ }
+
+ $store = array();
+ $_store = 0;
+
+ // capture html elements not to be messed with
+ $_offset = 0;
+ if (preg_match_all(
+
'#(<script[^>]*>.*?</script[^>]*>)|(<textarea[^>]*>.*?</textarea[^>]*>)|(<pre[^>]*>.*?</pre[^>]*>)#is',
+ $text,
+ $matches,
+ PREG_OFFSET_CAPTURE | PREG_SET_ORDER
+ )
+ ) {
+ foreach ($matches as $match) {
+ $store[] = $match[ 0 ][ 0 ];
+ $_length = strlen($match[ 0 ][ 0 ]);
+ $replace = '@!@SMARTY:' . $_store . ':SMARTY@!@';
+ $text = substr_replace($text, $replace, $match[ 0 ][ 1 ] -
$_offset, $_length);
+ $_offset += $_length - strlen($replace);
+ $_store++;
+ }
+ }
+ $expressions = array(// replace multiple spaces between tags by a
single space
+ '#(:SMARTY@!@|>)[\040\011]+(?=@!@SMARTY:|<)#s'
=> '\1 \2',
+ // remove newline between tags
+
'#(:SMARTY@!@|>)[\040\011]*[\n]\s*(?=@!@SMARTY:|<)#s' =>
'\1\2',
+ // remove multiple spaces between attributes (but
not in attribute values!)
+
'#(([a-z0-9]\s*=\s*("[^"]*?")|(\'[^\']*?\'))|<[a-z0-9_]+)\s+([a-z/>])#is' =>
'\1 \5',
+ '#>[\040\011]+$#Ss'
=> '> ',
+ '#>[\040\011]*[\n]\s*$#Ss'
=> '>',
+ $this->stripRegEx
=> '',
+ );
+ $text = preg_replace(array_keys($expressions),
array_values($expressions), $text);
+ $_offset = 0;
+ if (preg_match_all(
+ '#@!@SMARTY:([0-9]+):SMARTY@!@#is',
+ $text,
+ $matches,
+ PREG_OFFSET_CAPTURE | PREG_SET_ORDER
+ )
+ ) {
+ foreach ($matches as $match) {
+ $_length = strlen($match[ 0 ][ 0 ]);
+ $replace = $store[ $match[ 1 ][ 0 ] ];
+ $text = substr_replace($text, $replace, $match[ 0 ][ 1 ] +
$_offset, $_length);
+ $_offset += strlen($replace) - $_length;
+ $_store++;
}
- return new Smarty_Internal_ParseTree_Text($text);
}
- return null;
+ return $text;
}
/**
Wolfgang
signature.asc
Description: PGP signature

