smarty-php / smarty-php/smarty
Smarty 5 regression: Template function `{call}` variables leak into caller scope under `extends:`
Nobody has claimed this yet.
- Dominant language
- PHP
- Stars
- 2.3k
- Forks
- 709
- PR merge metrics
- No merged PRs in 30d
Description
Variables assigned inside a {function} (both parameters and internal {assign}s) leak into the calling scope when the template is rendered through the extends: resource (template inheritance). The identical construct is correctly isolated in a plain template, and behaved correctly in Smarty 4.
This is the same symptom as #952 ("Function scoped variables overwriting parent scope"), which was fixed for plain templates by #954 - but that fix does not cover the inheritance path, so the leak still occurs there in 5.8.2.
Steps to reproduce
Self-contained script (writes its own templates):
<?php
require 'vendor/autoload.php';
use Smarty\Smarty;
$dir = sys_get_temp_dir() . '/smrepro';
@mkdir($dir . '/templates', 0777, true);
@mkdir($dir . '/compiled', 0777, true);
array_map('unlink', glob($dir . '/compiled/*'));
// A template function that assigns a variable internally:
$fn = '{function name=test}{assign var="x" value="INNER"}{/function}' . "\n";
// Caller assigns its own $x, calls the function, then prints $x:
$logic = '{assign var="x" value="OUTER"}{test}x={$x}';
// Case A - plain template (no inheritance)
file_put_contents("$dir/templates/plain.tpl", $fn . $logic);
// Case B - same logic, but inside a {block} of a child that extends a parent
file_put_contents("$dir/templates/parent.tpl", '{block name=content}{/block}');
file_put_contents("$dir/templates/child.tpl", $fn . '{block name=content}' . $logic . '{/block}');
$smarty = new Smarty();
$smarty->setTemplateDir("$dir/templates")->setCompileDir("$dir/compiled");
$smarty->setForceCompile(true);
echo 'Smarty ' . Smarty::SMARTY_VERSION . "\n";
echo 'plain : ' . $smarty->fetch('plain.tpl') . " (expected: x=OUTER)\n";
echo 'extends: ' . $smarty->fetch('extends:parent.tpl|child.tpl') . " (expected: x=OUTER)\n";
Expected vs. actual
Expected: both print x=OUTER - the function's local assignment must not persist outside it.
| Smarty version | plain template | under extends: |
|---|---|---|
| 4.5.6 | x=OUTER |
x=OUTER |
| 5.8.2 | x=OUTER |
x=INNER (leak) |
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the self-contained PHP reproduction and compare the plain-template path with the extends:parent.tpl|child.tpl path. Trace the inheritance rendering path alongside the fix referenced in #954; done means both cases preserve x=OUTER on Smarty 5 without regressing plain templates.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php
- Domain
- web-dev
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 64/100