From 919861014a4aed6c644588b148e6f13a4baf757a Mon Sep 17 00:00:00 2001 From: uwetews Date: Thu, 17 Dec 2015 21:32:36 +0100 Subject: [PATCH] - bugfix using {block append/prepend} on same block in multiple levels of inheritance templates could fail (forum topic 25827) --- change_log.txt | 2 +- libs/Smarty.class.php | 2 +- .../smarty_internal_compile_block.php | 2 +- .../smarty_internal_runtime_inheritance.php | 76 +++++++++++-------- 4 files changed, 49 insertions(+), 33 deletions(-) diff --git a/change_log.txt b/change_log.txt index 9e9ea621..bfa166d2 100644 --- a/change_log.txt +++ b/change_log.txt @@ -1,7 +1,7 @@  ===== 3.1.29-dev ===== (xx.xx.2015) 17.12.2015 - bugfix {$smarty.capture.nameFail} did lowercase capture name https://github.com/smarty-php/smarty/issues/135 - + - bugfix using {block append/prepend} on same block in multiple levels of inheritance templates could fail (forum topic 25827) 16.12.2015 - bugfix {foreach} did fail if from atrribute is a Generator class https://github.com/smarty-php/smarty/issues/128 - bugfix direct access $smarty->template_dir = 'foo'; should call Smarty::setTemplateDir() https://github.com/smarty-php/smarty/issues/121 diff --git a/libs/Smarty.class.php b/libs/Smarty.class.php index eb57b94d..3ede5b3a 100644 --- a/libs/Smarty.class.php +++ b/libs/Smarty.class.php @@ -118,7 +118,7 @@ class Smarty extends Smarty_Internal_TemplateBase /** * smarty version */ - const SMARTY_VERSION = '3.1.29-dev/8'; + const SMARTY_VERSION = '3.1.29-dev/9'; /** * define variable scopes diff --git a/libs/sysplugins/smarty_internal_compile_block.php b/libs/sysplugins/smarty_internal_compile_block.php index 52a541eb..ab1fc6e0 100644 --- a/libs/sysplugins/smarty_internal_compile_block.php +++ b/libs/sysplugins/smarty_internal_compile_block.php @@ -142,7 +142,7 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_Compile_Shared_Inher } $compiler->suppressNocacheProcessing = true; $compiler->has_code = true; - $output = "ext->_inheritance->processBlock(\$_smarty_tpl, 3, {$compiler->_cache['blockName'][$compiler->_cache['blockNesting']]}, null, \$_blockParentStack);\n?>\n"; + $output = "ext->_inheritance->processBlock(\$_smarty_tpl, 4, {$compiler->_cache['blockName'][$compiler->_cache['blockNesting']]}, null, \$_blockParentStack);\n?>\n"; return $output; } } diff --git a/libs/sysplugins/smarty_internal_runtime_inheritance.php b/libs/sysplugins/smarty_internal_runtime_inheritance.php index ed21281d..3362182c 100644 --- a/libs/sysplugins/smarty_internal_runtime_inheritance.php +++ b/libs/sysplugins/smarty_internal_runtime_inheritance.php @@ -127,8 +127,11 @@ class Smarty_Internal_Runtime_Inheritance * - search in inheritance template hierarchy for child blocks * if found call it, otherwise ignore * - * $type 3 = {$smarty.block.parent}: - * - get block id from parent stack and call parent block + * $type 3 = {block append} {block prepend}: + * - call parent block + * + * $type 4 = {$smarty.block.parent}: + * - call parent block * * @param \Smarty_Internal_Template $tpl template object of caller * @param int $type call type see above @@ -140,16 +143,22 @@ class Smarty_Internal_Runtime_Inheritance */ public function processBlock(Smarty_Internal_Template $tpl, $type = 0, $name, $block, $callStack = array()) { - if (!isset($this->blockParameter[$name])) { - $this->blockParameter[$name] = array(); + if (!isset($this->blockParameter[ $name ])) { + $this->blockParameter[ $name ] = array(); } if ($this->state == 1) { - $block[2] = count($this->blockParameter[$name]); - $block[3] = $this->tplIndex; - $this->blockParameter[$name][] = $block; + $block[ 2 ] = count($this->blockParameter[ $name ]); + $block[ 3 ] = $this->tplIndex; + $this->blockParameter[ $name ][] = $block; return; } if ($type == 3) { + if (!empty($callStack)) { + $block = array_shift($callStack); + } else { + return; + } + } elseif ($type == 4) { if (!empty($callStack)) { array_shift($callStack); if (empty($callStack)) { @@ -160,23 +169,23 @@ class Smarty_Internal_Runtime_Inheritance return; } } else { - $blockParameter = &$this->blockParameter[$name]; + $index = 0; + $blockParameter = &$this->blockParameter[ $name ]; if ($type == 0) { - $index = $block[2] = count($blockParameter); - $block[3] = $this->tplIndex; + $index = $block[ 2 ] = count($blockParameter); + $block[ 3 ] = $this->tplIndex; $callStack = array(&$block); } elseif ($type == 1) { - $block[3] = $callStack[0][3]; - $index = 0; + $block[ 3 ] = $callStack[ 0 ][ 3 ]; for ($i = 0; $i < count($blockParameter); $i ++) { - if ($blockParameter[$i][3] <= $block[3]) { - $index = $blockParameter[$i][2]; + if ($blockParameter[ $i ][ 3 ] <= $block[ 3 ]) { + $index = $blockParameter[ $i ][ 2 ]; } } - $block[2] = $index; + $block[ 2 ] = $index; $callStack = array(&$block); - } else { - $index = $callStack[0][2]; + } elseif ($type == 2) { + $index = $callStack[ 0 ][ 2 ]; if ($index == 0) { return; } @@ -184,29 +193,36 @@ class Smarty_Internal_Runtime_Inheritance } $index --; // find lowest level child block - while ($index >= 0 && ($type || !$block[1])) { - $block = &$blockParameter[$index]; + while ($index >= 0 && ($type || !$block[ 1 ])) { + $block = &$blockParameter[ $index ]; array_unshift($callStack, $block); - if ($block[1]) { + if ($block[ 1 ]) { break; } $index --; } - if (isset($block['hide']) && $index <= 0) { + if (isset($block[ 'hide' ]) && $index <= 0) { return; } } $this->blockNesting ++; - if (isset($block['append'])) { - $this->processBlock($tpl, 3, $name, null, $callStack); + // {block append} ? + if (isset($block[ 'append' ])) { + $appendStack = $callStack; + if ($type == 0) { + array_shift($appendStack); + } + $this->processBlock($tpl, 3, $name, null, $appendStack); } - if (isset($block[6])) { - $block[6]($tpl, $callStack); - } else { - $block[0]($tpl, $callStack); - } - if (isset($block['prepend'])) { - $this->processBlock($tpl, 3, $name, null, $callStack); + // call block of current stack level + $block[ 0 ]($tpl, $callStack); + // {block prepend} ? + if (isset($block[ 'prepend' ])) { + $prependStack = $callStack; + if ($type == 0) { + array_shift($prependStack); + } + $this->processBlock($tpl, 3, $name, null, $prependStack); } $this->blockNesting --; }