diff --git a/Mustache.php b/Mustache.php index 022488b..9ec1f84 100644 --- a/Mustache.php +++ b/Mustache.php @@ -14,7 +14,7 @@ */ class Mustache { - const VERSION = '0.8.0'; + const VERSION = '0.8.1'; const SPEC_VERSION = '1.1.2'; /** @@ -90,9 +90,9 @@ class Mustache { * // opening and closing delimiters, as an array or a space-separated string * 'delimiters' => '<% %>', * - * // an array of pragmas to enable + * // an array of pragmas to enable/disable * 'pragmas' => array( - * Mustache::PRAGMA_UNESCAPED + * Mustache::PRAGMA_UNESCAPED => true * ), * ); * @@ -132,8 +132,8 @@ class Mustache { } if (isset($options['pragmas'])) { - foreach ($options['pragmas'] as $pragma_name) { - if (!in_array($pragma_name, $this->_pragmasImplemented)) { + foreach ($options['pragmas'] as $pragma_name => $pragma_value) { + if (!in_array($pragma_name, $this->_pragmasImplemented, true)) { throw new MustacheException('Unknown pragma: ' . $pragma_name, MustacheException::UNKNOWN_PRAGMA); } } diff --git a/test/MustacheInjectionTest.php b/test/MustacheInjectionTest.php new file mode 100644 index 0000000..de74943 --- /dev/null +++ b/test/MustacheInjectionTest.php @@ -0,0 +1,127 @@ + '{{ b }}', + 'b' => 'FAIL' + ); + $template = '{{ a }}'; + $output = '{{ b }}'; + $m = new Mustache(); + $this->assertEquals($output, $m->render($template, $data)); + } + + public function testUnescapedInterpolationInjection() { + $data = array( + 'a' => '{{ b }}', + 'b' => 'FAIL' + ); + $template = '{{{ a }}}'; + $output = '{{ b }}'; + $m = new Mustache(); + $this->assertEquals($output, $m->render($template, $data)); + } + + + // sections + + public function testSectionInjection() { + $data = array( + 'a' => true, + 'b' => '{{ c }}', + 'c' => 'FAIL' + ); + $template = '{{# a }}{{ b }}{{/ a }}'; + $output = '{{ c }}'; + $m = new Mustache(); + $this->assertEquals($output, $m->render($template, $data)); + } + + public function testUnescapedSectionInjection() { + $data = array( + 'a' => true, + 'b' => '{{ c }}', + 'c' => 'FAIL' + ); + $template = '{{# a }}{{{ b }}}{{/ a }}'; + $output = '{{ c }}'; + $m = new Mustache(); + $this->assertEquals($output, $m->render($template, $data)); + } + + + // partials + + public function testPartialInjection() { + $data = array( + 'a' => '{{ b }}', + 'b' => 'FAIL' + ); + $template = '{{> partial }}'; + $partials = array( + 'partial' => '{{ a }}', + ); + $output = '{{ b }}'; + $m = new Mustache(); + $this->assertEquals($output, $m->render($template, $data, $partials)); + } + + public function testPartialUnescapedInjection() { + $data = array( + 'a' => '{{ b }}', + 'b' => 'FAIL' + ); + $template = '{{> partial }}'; + $partials = array( + 'partial' => '{{{ a }}}', + ); + $output = '{{ b }}'; + $m = new Mustache(); + $this->assertEquals($output, $m->render($template, $data, $partials)); + } + + + // lambdas + + public function testLambdaInterpolationInjection() { + $data = array( + 'a' => array($this, 'interpolationLambda'), + 'b' => '{{ c }}', + 'c' => 'FAIL' + ); + $template = '{{ a }}'; + $output = '{{ c }}'; + $m = new Mustache(); + $this->assertEquals($output, $m->render($template, $data)); + } + + public function interpolationLambda() { + return '{{ b }}'; + } + + public function testLambdaSectionInjection() { + $data = array( + 'a' => array($this, 'sectionLambda'), + 'b' => '{{ c }}', + 'c' => 'FAIL' + ); + $template = '{{# a }}b{{/ a }}'; + $output = '{{ c }}'; + $m = new Mustache(); + $this->assertEquals($output, $m->render($template, $data)); + } + + public function sectionLambda($content) { + return '{{ ' . $content . ' }}'; + } + +} \ No newline at end of file diff --git a/test/MustacheTest.php b/test/MustacheTest.php index 1a06b46..0c0bb13 100644 --- a/test/MustacheTest.php +++ b/test/MustacheTest.php @@ -94,21 +94,21 @@ class MustacheTest extends PHPUnit_Framework_TestCase { array( 'charset' => 'UTF-8', 'delimiters' => '<< >>', - 'pragmas' => array(Mustache::PRAGMA_UNESCAPED) + 'pragmas' => array(Mustache::PRAGMA_UNESCAPED => true) ), 'UTF-8', array('<<', '>>'), - array(Mustache::PRAGMA_UNESCAPED), + array(Mustache::PRAGMA_UNESCAPED => true), ), array( array( 'charset' => 'cp866', 'delimiters' => array('[[[[', ']]]]'), - 'pragmas' => array(Mustache::PRAGMA_UNESCAPED) + 'pragmas' => array(Mustache::PRAGMA_UNESCAPED => true) ), 'cp866', array('[[[[', ']]]]'), - array(Mustache::PRAGMA_UNESCAPED), + array(Mustache::PRAGMA_UNESCAPED => true), ), ); } @@ -117,7 +117,7 @@ class MustacheTest extends PHPUnit_Framework_TestCase { * @expectedException MustacheException */ public function testConstructorInvalidPragmaOptionsThrowExceptions() { - $mustache = new Mustache(null, null, null, array('pragmas' => array('banana phone'))); + $mustache = new Mustache(null, null, null, array('pragmas' => array('banana phone' => true))); } /** @@ -195,7 +195,7 @@ class MustacheTest extends PHPUnit_Framework_TestCase { $this->assertEquals('Charlie Chaplin', $m->render(null, array('first_name' => 'Charlie', 'last_name' => 'Chaplin'))); $this->assertEquals('Zappa, Frank', $m->render('{{last_name}}, {{first_name}}', array('first_name' => 'Frank', 'last_name' => 'Zappa'))); } - + /** * @group interpolation * @dataProvider interpolationData