From 824ae885c6ef9ea33e1fadcd233f87b6a175a3a9 Mon Sep 17 00:00:00 2001 From: Dmitriy Simushev Date: Mon, 1 Jun 2015 15:15:52 +0000 Subject: [PATCH] Fix escaping of tags with multiple slashes --- src/Handlebars/Tokenizer.php | 12 ++++++++++-- tests/Xamin/HandlebarsTest.php | 10 ++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/Handlebars/Tokenizer.php b/src/Handlebars/Tokenizer.php index f3557bb..3562477 100644 --- a/src/Handlebars/Tokenizer.php +++ b/src/Handlebars/Tokenizer.php @@ -149,7 +149,15 @@ class Tokenizer switch ($this->state) { case self::IN_TEXT: - if ($this->tagChange($this->otag. self::T_TRIM, $text, $i) and !$this->escaped) { + // Handlebars.js does not think that openning curly brace in + // "\\\{{data}}" template is escaped. Instead it removes one + // slash and leaves others "as is". To emulate similar behavior + // we have to check the last character in the buffer. If it's a + // slash we actually does not need to escape openning curly + // brace. + $prev_slash = substr($this->buffer, -1) == '\\'; + + if ($this->tagChange($this->otag. self::T_TRIM, $text, $i) and (!$this->escaped || $prev_slash)) { $this->flushBuffer(); $this->state = self::IN_TAG_TYPE; $this->trimLeft = true; @@ -157,7 +165,7 @@ class Tokenizer $this->buffer .= "{{{"; $i += 2; continue; - } elseif ($this->tagChange($this->otag, $text, $i) and !$this->escaped) { + } elseif ($this->tagChange($this->otag, $text, $i) and (!$this->escaped || $prev_slash)) { $i--; $this->flushBuffer(); $this->state = self::IN_TAG_TYPE; diff --git a/tests/Xamin/HandlebarsTest.php b/tests/Xamin/HandlebarsTest.php index 607ff3b..517549c 100644 --- a/tests/Xamin/HandlebarsTest.php +++ b/tests/Xamin/HandlebarsTest.php @@ -127,6 +127,16 @@ class HandlebarsTest extends \PHPUnit_Framework_TestCase array('data' => 'foo'), '\\foo' // is equals to \foo in output ), + array( + '\\\\\\{{data}}', // is equal to \\\{{data}} in template file + array('data' => 'foo'), + '\\\\foo' // is equals to \\foo in output + ), + array( + '\\\\\\\\{{data}}', // is equal to \\\\{{data}} in template file + array('data' => 'foo'), + '\\\\\\foo' // is equals to \\\foo in output + ), array( '\{{{data}}}', // is equal to \{{{data}}} in template file array('data' => 'foo'),