From f7543e4c9a176a4a7e02f3bfb1c4c94f12918e2c Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Mon, 18 Aug 2025 22:09:31 +0900 Subject: [PATCH] In template v2, process escape filters before other filters --- .../parsers/template/TemplateParser_v2.php | 14 +++++++++++--- .../framework/parsers/TemplateParserV2Test.php | 14 ++++++++++++-- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/common/framework/parsers/template/TemplateParser_v2.php b/common/framework/parsers/template/TemplateParser_v2.php index 399e45d97..f405eb2ad 100644 --- a/common/framework/parsers/template/TemplateParser_v2.php +++ b/common/framework/parsers/template/TemplateParser_v2.php @@ -872,7 +872,16 @@ class TemplateParser_v2 $str = $this->_escapeCurly($str); $str = $this->_convertVariableScope($str); - // Apply filters. + // Process the escape option first. + foreach ($filters as $filter) + { + if (in_array($filter, ['autoescape', 'autolang', 'escape', 'noescape'])) + { + $escape_option = $filter; + } + } + + // Apply other filters. foreach ($filters as $filter) { // Separate the filter option from the filter name. @@ -891,14 +900,13 @@ class TemplateParser_v2 } } - // Apply each filter. + // Apply filters. switch ($filter) { case 'autoescape': case 'autolang': case 'escape': case 'noescape': - $escape_option = $filter; break; case 'escapejs': case 'js': diff --git a/tests/unit/framework/parsers/TemplateParserV2Test.php b/tests/unit/framework/parsers/TemplateParserV2Test.php index d220f4da9..f743ff618 100644 --- a/tests/unit/framework/parsers/TemplateParserV2Test.php +++ b/tests/unit/framework/parsers/TemplateParserV2Test.php @@ -446,9 +446,19 @@ class TemplateParserV2Test extends \Codeception\Test\Unit $target = "foo ?? '', \ENT_QUOTES, 'UTF-8', false)); ?>"; $this->assertEquals($target, $this->_parse($source)); - // nl2br() with gratuitous escape + // nl2br() with extra escape $source = '{{ $foo|nl2br|escape }}'; - $target = "foo ?? '', \ENT_QUOTES, 'UTF-8', false)), \ENT_QUOTES, 'UTF-8', true); ?>"; + $target = "foo ?? '', \ENT_QUOTES, 'UTF-8', true)); ?>"; + $this->assertEquals($target, $this->_parse($source)); + + // nl2br() with noescape + $source = '{{ $foo|nl2br|noescape }}'; + $target = "foo ?? ''); ?>"; + $this->assertEquals($target, $this->_parse($source)); + + // nl2br() with noescape and autoescape + $source = '{{ $foo|noescape|nl2br|autoescape }}'; + $target = "foo ?? '', \ENT_QUOTES, 'UTF-8', false)); ?>"; $this->assertEquals($target, $this->_parse($source)); // Array join (default joiner is comma)