Global variables are restored properly after template function call

92 views
Skip to first unread message

Francisco Alcaraz

unread,
Mar 20, 2015, 12:41:16 PM3/20/15
to smarty-d...@googlegroups.com
Hi guys,

I would like to report a problem we have detected dealing with template functions and related to global variables management.

The root cause is clear: at the end of the function all the vars are restored to their values before the function call, and then, only those global vars not already set in the tpl_vars array, are copied.

The error is due the copy is not done for all the global vars, so you are restoring the values they had at the beginning of the function call, and do not to their last values, what is not correct if the function has modified them.


Code generated at the end of the template function:
<?php $_smarty_tpl->tpl_vars = $saved_tpl_vars;
foreach (Smarty::$global_tpl_vars as $key => $value) if(!isset($_smarty_tpl->tpl_vars[$key])) $_smarty_tpl->tpl_vars[$key] = $value;}}?>


Proposed code fixing the problem (just removing the if):
<?php $_smarty_tpl->tpl_vars = $saved_tpl_vars;
foreach (Smarty::$global_tpl_vars as $key => $value) $_smarty_tpl->tpl_vars[$key] = $value;}}?>



The change to be done is in smarty/libs/sysplugins/smarty_internal_compile_function.php
151c151
< foreach (Smarty::\$global_tpl_vars as \$key => \$value) if(!isset(\$_smarty_tpl->tpl_vars[\$key])) \$_smarty_tpl->tpl_vars[\$key] = \$value;}}?>\n";
---
> foreach (Smarty::\$global_tpl_vars as \$key => \$value) \$_smarty_tpl->tpl_vars[\$key] = \$value;}}?>\n";


Example:
{function calculate}
{$var1=$var1+1 scope=global}
inside = {$var1}
{/function}
     
{$var1=1 scope=global}
{calculate}
{calculate}
outside = {$var1}


output with the error:
inside = 2
inside = 2
outside = 1


output after the fixing:
inside = 2
inside = 3
outside = 3



uwe.tews

unread,
Mar 20, 2015, 1:27:18 PM3/20/15
to smarty-d...@googlegroups.com
You are right for your example.
But your patch does not work in this case:

global variable 'foo' = 1;

user reassigns 'foo' in local template scope 'foo' = 2;
he calls a template function (not touching any variable)
back in template scope 'foo' is now modified to 'foo' = 1;

But I think I got it now:
foreach (Smarty::$global_tpl_vars as $key => $value){
if ($_smarty_tpl->tpl_vars[$key] === $value) $saved_tpl_vars[$key] = $value;
}
$_smarty_tpl->tpl_vars = $saved_tpl_vars;


It's updated on Github and the fix will be included in 3.1.22
Reply all
Reply to author
Forward
0 new messages