Skip to content

Smarty 5 regression: Template function {call} variables leak into caller scope under extends: #1196

Description

@m-ober

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions