Skip to content

Commit 2877ecc

Browse files
authored
Merge pull request #7142 from kenjis/fix-parser-exclamation-mark
fix: [Parser] `!` does not work if delimiters are changed
2 parents 5e25ac7 + a5bce2f commit 2877ecc

2 files changed

Lines changed: 21 additions & 3 deletions

File tree

system/View/Parser.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,9 @@ protected function parse(string $template, array $data = [], ?array $options = n
257257
*/
258258
protected function parseSingle(string $key, string $val): array
259259
{
260-
$pattern = '#' . $this->leftDelimiter . '!?\s*' . preg_quote($key, '#') . '(?(?=\s*\|\s*)(\s*\|*\s*([|\w<>=\(\),:.\-\s\+\\\\/]+)*\s*))(\s*)!?' . $this->rightDelimiter . '#ums';
260+
$pattern = '#' . $this->leftDelimiter . '!?\s*' . preg_quote($key, '#')
261+
. '(?(?=\s*\|\s*)(\s*\|*\s*([|\w<>=\(\),:.\-\s\+\\\\/]+)*\s*))(\s*)!?'
262+
. $this->rightDelimiter . '#ums';
261263

262264
return [$pattern => $val];
263265
}
@@ -506,7 +508,10 @@ protected function replaceSingle($pattern, $content, $template, bool $escape = f
506508
// Replace the content in the template
507509
return preg_replace_callback($pattern, function ($matches) use ($content, $escape) {
508510
// Check for {! !} syntax to not escape this one.
509-
if (strpos($matches[0], '{!') === 0 && substr($matches[0], -2) === '!}') {
511+
if (
512+
strpos($matches[0], $this->leftDelimiter . '!') === 0
513+
&& substr($matches[0], -1 - strlen($this->rightDelimiter)) === '!' . $this->rightDelimiter
514+
) {
510515
$escape = false;
511516
}
512517

tests/system/View/ParserTest.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -600,11 +600,24 @@ public function testParserNoEscape()
600600
'title' => '<script>Heroes</script>',
601601
];
602602

603-
$template = '{! title!}';
603+
$template = '{! title !}';
604604
$this->parser->setData($data);
605605
$this->assertSame('<script>Heroes</script>', $this->parser->renderString($template));
606606
}
607607

608+
public function testParserNoEscapeAndDelimiterChange()
609+
{
610+
$this->parser->setDelimiters('{{', '}}');
611+
612+
$data = [
613+
'title' => '<script>Heroes</script>',
614+
];
615+
$this->parser->setData($data);
616+
617+
$template = '{{! title !}}';
618+
$this->assertSame('<script>Heroes</script>', $this->parser->renderString($template));
619+
}
620+
608621
public function testIgnoresComments()
609622
{
610623
$data = [

0 commit comments

Comments
 (0)