diff --git a/src/Mustache/Tokenizer.php b/src/Mustache/Tokenizer.php index bf1e5d1..c4ad3ea 100644 --- a/src/Mustache/Tokenizer.php +++ b/src/Mustache/Tokenizer.php @@ -151,7 +151,7 @@ class Mustache_Tokenizer default: if ($this->tagChange($this->ctag, $this->ctagLen, $text, $i)) { - $this->tokens[] = array( + $token = array( self::TYPE => $this->tagType, self::NAME => trim($this->buffer), self::OTAG => $this->otag, @@ -160,20 +160,31 @@ class Mustache_Tokenizer self::INDEX => ($this->tagType === self::T_END_SECTION) ? $this->seenTag - $this->otagLen : $i + $this->ctagLen ); - $this->buffer = ''; - $i += $this->ctagLen - 1; - $this->state = self::IN_TEXT; if ($this->tagType === self::T_UNESCAPED) { + // Clean up `{{{ tripleStache }}}` style tokens. if ($this->ctag === '}}') { - $i++; + if (($i < $len + 1) && $text[$i+2] == '}') { + $i++; + } else { + $msg = sprintf( + 'Uneven closing tag encountered: on line %d', + $token[Mustache_Tokenizer::LINE] + ); + + throw new Mustache_Exception_SyntaxException($msg, $token); + } } else { - // Clean up `{{{ tripleStache }}}` style tokens. - $lastName = $this->tokens[count($this->tokens) - 1][self::NAME]; + $lastName = $token[self::NAME]; if (substr($lastName, -1) === '}') { - $this->tokens[count($this->tokens) - 1][self::NAME] = trim(substr($lastName, 0, -1)); + $token[self::NAME] = trim(substr($lastName, 0, -1)); } } } + + $this->buffer = ''; + $i += $this->ctagLen - 1; + $this->state = self::IN_TEXT; + $this->tokens[] = $token; } else { $this->buffer .= $text[$i]; } diff --git a/test/Mustache/Test/TokenizerTest.php b/test/Mustache/Test/TokenizerTest.php index 42df8e1..ce24f56 100644 --- a/test/Mustache/Test/TokenizerTest.php +++ b/test/Mustache/Test/TokenizerTest.php @@ -24,6 +24,17 @@ class Mustache_Test_TokenizerTest extends PHPUnit_Framework_TestCase $this->assertSame($expected, $tokenizer->scan($text, $delimiters)); } + /** + * @expectedException Mustache_Exception_SyntaxException + */ + public function testUnevenBracesThrowExceptions() + { + $tokenizer = new Mustache_Tokenizer; + + $text = "{{{ name }}"; + $tokenizer->scan($text, null); + } + public function getTokens() { return array(