diff --git a/src/Mustache/Compiler.php b/src/Mustache/Compiler.php index 9c32fa0..dcc9469 100644 --- a/src/Mustache/Compiler.php +++ b/src/Mustache/Compiler.php @@ -246,7 +246,7 @@ class Mustache_Compiler $method = $this->getFindMethod($id); $id = var_export($id, true); - return sprintf($this->prepare(self::BLOCK_ARG, $level), $key, $key, $id, $this->flushIndent()); + return sprintf($this->prepare(self::BLOCK_ARG, $level), $id, $key, $id, $this->flushIndent()); } const SECTION_CALL = ' diff --git a/src/Mustache/Context.php b/src/Mustache/Context.php index ca82c35..96089ce 100644 --- a/src/Mustache/Context.php +++ b/src/Mustache/Context.php @@ -134,7 +134,7 @@ class Mustache_Context public function findInBlock($id) { foreach($this->block_stack as $context) { - if (is_array($context) && array_key_exists($id, $context)) { + if (array_key_exists($id, $context)) { return $context[$id]; } } diff --git a/src/Mustache/Parser.php b/src/Mustache/Parser.php index 448e229..d331db2 100644 --- a/src/Mustache/Parser.php +++ b/src/Mustache/Parser.php @@ -60,11 +60,13 @@ class Mustache_Parser switch ($token[Mustache_Tokenizer::TYPE]) { case Mustache_Tokenizer::T_DELIM_CHANGE: + $this->checkIfTokenIsAllowedInParent($parent, $token); $this->clearStandaloneLines($nodes, $tokens); break; case Mustache_Tokenizer::T_SECTION: case Mustache_Tokenizer::T_INVERTED: + $this->checkIfTokenIsAllowedInParent($parent, $token); $this->clearStandaloneLines($nodes, $tokens); $nodes[] = $this->buildTree($tokens, $token); break; @@ -97,6 +99,7 @@ class Mustache_Parser return $parent; case Mustache_Tokenizer::T_PARTIAL: + $this->checkIfTokenIsAllowedInParent($parent, $token); //store the whitespace prefix for laters! if ($indent = $this->clearStandaloneLines($nodes, $tokens)) { $token[Mustache_Tokenizer::INDENT] = $indent[Mustache_Tokenizer::VALUE]; @@ -105,11 +108,12 @@ class Mustache_Parser break; case Mustache_Tokenizer::T_PARENT: + $this->checkIfTokenIsAllowedInParent($parent, $token); $nodes[] = $this->buildTree($tokens, $token); break; case Mustache_Tokenizer::T_BLOCK_VAR: - if ($parent[Mustache_Tokenizer::TYPE] == Mustache_Tokenizer::T_PARENT) { + if ($parent[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_PARENT) { $token[Mustache_Tokenizer::TYPE] = Mustache_Tokenizer::T_BLOCK_ARG; } $this->clearStandaloneLines($nodes, $tokens); @@ -215,4 +219,11 @@ class Mustache_Parser return false; } + + private function checkIfTokenIsAllowedInParent($parent, $token) + { + if ($parent[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_PARENT) { + throw new Mustache_Exception_SyntaxException('Illegal content in < parent tag', $token); + } + } } diff --git a/test/Mustache/Test/Functional/InheritanceTest.php b/test/Mustache/Test/Functional/InheritanceTest.php index d1e01af..bbd4969 100644 --- a/test/Mustache/Test/Functional/InheritanceTest.php +++ b/test/Mustache/Test/Functional/InheritanceTest.php @@ -322,7 +322,7 @@ class Mustache_Test_Functional_InheritanceTest extends PHPUnit_Framework_TestCas $this->assertEquals('hmm', $tpl->render($data)); } - public function IgnoreTextInsideSuperTemplates() + public function testIgnoreTextInsideSuperTemplates() { $partials = array( 'include' => '{{$foo}}default content{{/foo}}' @@ -338,4 +338,27 @@ class Mustache_Test_Functional_InheritanceTest extends PHPUnit_Framework_TestCas $this->assertEquals('default content', $tpl->render($data)); } + + /** + * @expectedException Mustache_Exception_SyntaxException + * @expectedExceptionMessage Illegal content in < parent tag + */ + public function testOnlyBlockTagsAllowedInParent() + { + $partials = array( + 'foo' => '{{$baz}}default content{{/baz}}' + ); + + $this->mustache->setPartials($partials); + + $tpl = $this->mustache->loadTemplate( + '{{< foo }}{{# bar }}{{$ baz }}{{/ baz }}{{/ bar }}{{/ foo }}' + ); + + $data = array( + 'bar' => 'set by user' + ); + + $tpl->render($data); + } }