From b85616c97233e79d8793f011feccfd093b322802 Mon Sep 17 00:00:00 2001 From: Gunnar Kreitz Date: Fri, 29 Nov 2024 09:10:36 +0100 Subject: [PATCH 1/3] Fix compiler plugin support for unnamed arguments --- src/Compile/Base.php | 15 +++++++++++++-- src/Compile/Tag/BCPluginWrapper.php | 16 +++++++++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/Compile/Base.php b/src/Compile/Base.php index 2d5c0c0ef..b8d6c9b2c 100644 --- a/src/Compile/Base.php +++ b/src/Compile/Base.php @@ -69,6 +69,17 @@ protected function formatParamsArray(array $_attr): array { return $_paramsArray; } + /** + * Returns attribute index for unnamed ("shorthand") attribute, or null if not allowed. + * + * @param int $key + * + * @return string|int|null + */ + protected function getShorthandOrder(int $key) { + return $this->shorttag_order[$key] ?? null; + } + /** * This function checks if the attributes passed are valid * The attributes passed for the tag to compile are checked against the list of required and @@ -91,8 +102,8 @@ protected function getAttributes($compiler, $attributes) { if (isset($options[trim($mixed, '\'"')])) { $_indexed_attr[trim($mixed, '\'"')] = true; // shorthand attribute ? - } elseif (isset($this->shorttag_order[$key])) { - $_indexed_attr[$this->shorttag_order[$key]] = $mixed; + } elseif (!is_null($this->getShorthandOrder($key))) { + $_indexed_attr[$this->getShorthandOrder($key)] = $mixed; } else { // too many shorthands $compiler->trigger_template_error('too many shorthand attributes', null, true); diff --git a/src/Compile/Tag/BCPluginWrapper.php b/src/Compile/Tag/BCPluginWrapper.php index abd89f78f..dfb174644 100644 --- a/src/Compile/Tag/BCPluginWrapper.php +++ b/src/Compile/Tag/BCPluginWrapper.php @@ -21,6 +21,20 @@ public function __construct($callback, bool $cacheable = true) { $this->cacheable = $cacheable; } + /** + * Returns attribute index for unnamed ("shorthand") attribute, or null if not allowed. + * + * For compiler plugins, we allow arbitrarily many unnamed attributes, + * and just make them accessible in the order they are set. + * + * @param int $key + * + * @return int + */ + protected function getShorthandOrder(int $key): int { + return $key; + } + /** * @inheritDoc */ @@ -28,4 +42,4 @@ public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = { return call_user_func($this->callback, $this->getAttributes($compiler, $args), $compiler->getSmarty()); } -} \ No newline at end of file +} From ff1214096c6c73d25a1d9f99ffbd5c08ebc4f4eb Mon Sep 17 00:00:00 2001 From: Gunnar Kreitz Date: Fri, 29 Nov 2024 09:11:07 +0100 Subject: [PATCH 2/3] Add test coverage of unnamed arguments in compiler plugins --- .../RegisterCompiler/RegisterCompilerFunctionTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/UnitTests/SmartyMethodsTests/RegisterCompiler/RegisterCompilerFunctionTest.php b/tests/UnitTests/SmartyMethodsTests/RegisterCompiler/RegisterCompilerFunctionTest.php index ec2287adf..1ce743436 100644 --- a/tests/UnitTests/SmartyMethodsTests/RegisterCompiler/RegisterCompilerFunctionTest.php +++ b/tests/UnitTests/SmartyMethodsTests/RegisterCompiler/RegisterCompilerFunctionTest.php @@ -34,7 +34,7 @@ public function testRegisterCompilerFunction() { $this->smarty->registerPlugin(Smarty::PLUGIN_COMPILER, 'testcompilerfunction', 'mycompilerfunction'); $this->assertEquals('mycompilerfunction', $this->smarty->getRegisteredPlugin('compiler', 'testcompilerfunction')[0]); - $this->assertEquals('hello world 1', $this->smarty->fetch('eval:{testcompilerfunction var=1}')); + $this->assertEquals('hello world 1 2', $this->smarty->fetch('eval:{testcompilerfunction 1 var=2}')); } /** @@ -99,7 +99,7 @@ public function testUnregisterCompilerFunctionOtherRegistered() function mycompilerfunction($params, $smarty) { - return ""; + return ""; } function mycompilerfunctionopen($params, $smarty) From 0d24f1dc2dd4e0df3f8a6d728eb2d66bb534bed4 Mon Sep 17 00:00:00 2001 From: Gunnar Kreitz Date: Fri, 17 Jan 2025 10:34:47 +0100 Subject: [PATCH 3/3] Change type annotation to mixed due to lack of guarantees on type From usage, it very much looks like the type will always be int, but on the off chance there is some code path where this gets called with something else, type was widened to mixed for now, per disussion in #1088 --- src/Compile/Base.php | 4 ++-- src/Compile/Tag/BCPluginWrapper.php | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Compile/Base.php b/src/Compile/Base.php index b8d6c9b2c..f028e893e 100644 --- a/src/Compile/Base.php +++ b/src/Compile/Base.php @@ -72,11 +72,11 @@ protected function formatParamsArray(array $_attr): array { /** * Returns attribute index for unnamed ("shorthand") attribute, or null if not allowed. * - * @param int $key + * @param string|int|null $key Index of the argument. Type should probably be narrowed to int * * @return string|int|null */ - protected function getShorthandOrder(int $key) { + protected function getShorthandOrder($key) { return $this->shorttag_order[$key] ?? null; } diff --git a/src/Compile/Tag/BCPluginWrapper.php b/src/Compile/Tag/BCPluginWrapper.php index dfb174644..e69634093 100644 --- a/src/Compile/Tag/BCPluginWrapper.php +++ b/src/Compile/Tag/BCPluginWrapper.php @@ -27,11 +27,11 @@ public function __construct($callback, bool $cacheable = true) { * For compiler plugins, we allow arbitrarily many unnamed attributes, * and just make them accessible in the order they are set. * - * @param int $key + * @param string|int|null $key Index of the argument. Type should probably be narrowed to int * - * @return int + * @return string|int|null */ - protected function getShorthandOrder(int $key): int { + protected function getShorthandOrder($key) { return $key; }