From 311f337856a9cfb63aea616eed4290162d23a718 Mon Sep 17 00:00:00 2001 From: Pixie Date: Sat, 27 Apr 2013 10:45:40 -0500 Subject: [PATCH] Allow passing in the $type parameter of htmlspecialchars() --- src/Mustache/Compiler.php | 9 +++++--- src/Mustache/Engine.php | 23 +++++++++++++++++-- test/Mustache/Test/CompilerTest.php | 35 ++++++++++++++++++++++++----- 3 files changed, 56 insertions(+), 11 deletions(-) diff --git a/src/Mustache/Compiler.php b/src/Mustache/Compiler.php index a95c919..dd0c52a 100644 --- a/src/Mustache/Compiler.php +++ b/src/Mustache/Compiler.php @@ -21,6 +21,7 @@ class Mustache_Compiler private $source; private $indentNextLine; private $customEscape; + private $entity_flags; private $charset; private $strictCallables; private $pragmas; @@ -32,18 +33,20 @@ class Mustache_Compiler * @param string $tree Parse tree of Mustache tokens * @param string $name Mustache Template class name * @param bool $customEscape (default: false) + * @param int $entity_flags (default: ENT_COMPAT) * @param string $charset (default: 'UTF-8') * @param bool $strictCallables (default: false) * * @return string Generated PHP source code */ - public function compile($source, array $tree, $name, $customEscape = false, $charset = 'UTF-8', $strictCallables = false) + public function compile($source, array $tree, $name, $customEscape = false, $charset = 'UTF-8', $strictCallables = false, $entity_flags = ENT_COMPAT) { $this->pragmas = array(); $this->sections = array(); $this->source = $source; $this->indentNextLine = true; $this->customEscape = $customEscape; + $this->entity_flags = $entity_flags; $this->charset = $charset; $this->strictCallables = $strictCallables; @@ -402,7 +405,7 @@ class Mustache_Compiler return preg_replace("/\n( {8})?/", "\n".str_repeat(" ", $bonus * 4), $text); } - const DEFAULT_ESCAPE = 'htmlspecialchars(%s, ENT_COMPAT, %s)'; + const DEFAULT_ESCAPE = 'htmlspecialchars(%s, %s, %s)'; const CUSTOM_ESCAPE = 'call_user_func($this->mustache->getEscape(), %s)'; /** @@ -417,7 +420,7 @@ class Mustache_Compiler if ($this->customEscape) { return sprintf(self::CUSTOM_ESCAPE, $value); } else { - return sprintf(self::DEFAULT_ESCAPE, $value, var_export($this->charset, true)); + return sprintf(self::DEFAULT_ESCAPE, $value, var_export($this->entity_flags, true), var_export($this->charset, true)); } } diff --git a/src/Mustache/Engine.php b/src/Mustache/Engine.php index 5f92d19..0d066d1 100644 --- a/src/Mustache/Engine.php +++ b/src/Mustache/Engine.php @@ -39,6 +39,7 @@ class Mustache_Engine private $partialsLoader; private $helpers; private $escape; + private $entity_flags = ENT_COMPAT; private $charset = 'UTF-8'; private $logger; private $strictCallables = false; @@ -81,6 +82,9 @@ class Mustache_Engine * return htmlspecialchars($buffer, ENT_COMPAT, 'UTF-8'); * }, * + * // Type argument for `htmlspecialchars`. Defaults to ENT_COMPAT. You may prefer ENT_QUOTES. + * 'entity_flags' => ENT_QUOTES, + * * // Character set for `htmlspecialchars`. Defaults to 'UTF-8'. Use 'UTF-8'. * 'charset' => 'ISO-8859-1', * @@ -139,6 +143,10 @@ class Mustache_Engine $this->escape = $options['escape']; } + if (isset($options['entity_flags'])) { + $this->entity_flags = $options['entity_flags']; + } + if (isset($options['charset'])) { $this->charset = $options['charset']; } @@ -180,6 +188,16 @@ class Mustache_Engine return $this->escape; } + /** + * Get the current Mustache entitity type to escape. + * + * @return int + */ + public function getEntityFlags() + { + return $this->entity_flags; + } + /** * Get the current Mustache character set. * @@ -471,9 +489,10 @@ class Mustache_Engine public function getTemplateClassName($source) { return $this->templateClassPrefix . md5(sprintf( - 'version:%s,escape:%s,charset:%s,strict_callables:%s,source:%s', + 'version:%s,escape:%s,entity_flags:%i,charset:%s,strict_callables:%s,source:%s', self::VERSION, isset($this->escape) ? 'custom' : 'default', + $this->entity_flags, $this->charset, $this->strictCallables ? 'true' : 'false', $source @@ -644,7 +663,7 @@ class Mustache_Engine array('className' => $name) ); - return $this->getCompiler()->compile($source, $tree, $name, isset($this->escape), $this->charset, $this->strictCallables); + return $this->getCompiler()->compile($source, $tree, $name, isset($this->escape), $this->charset, $this->strictCallables, $this->entity_flags); } /** diff --git a/test/Mustache/Test/CompilerTest.php b/test/Mustache/Test/CompilerTest.php index bd94073..03b2ef2 100644 --- a/test/Mustache/Test/CompilerTest.php +++ b/test/Mustache/Test/CompilerTest.php @@ -18,11 +18,11 @@ class Mustache_Test_CompilerTest extends PHPUnit_Framework_TestCase /** * @dataProvider getCompileValues */ - public function testCompile($source, array $tree, $name, $customEscaper, $charset, $expected) + public function testCompile($source, array $tree, $name, $customEscaper, $entity_flags, $charset, $expected) { $compiler = new Mustache_Compiler; - $compiled = $compiler->compile($source, $tree, $name, $customEscaper, $charset); + $compiled = $compiler->compile($source, $tree, $name, $customEscaper, $charset, false, $entity_flags); foreach ($expected as $contains) { $this->assertContains($contains, $compiled); } @@ -31,12 +31,12 @@ class Mustache_Test_CompilerTest extends PHPUnit_Framework_TestCase public function getCompileValues() { return array( - array('', array(), 'Banana', false, 'ISO-8859-1', array( + array('', array(), 'Banana', false, ENT_COMPAT, 'ISO-8859-1', array( "\nclass Banana extends Mustache_Template", 'return $buffer;', )), - array('', array($this->createTextToken('TEXT')), 'Monkey', false, 'UTF-8', array( + array('', array($this->createTextToken('TEXT')), 'Monkey', false, ENT_COMPAT, 'UTF-8', array( "\nclass Monkey extends Mustache_Template", '$buffer .= $indent . \'TEXT\';', 'return $buffer;', @@ -52,6 +52,7 @@ class Mustache_Test_CompilerTest extends PHPUnit_Framework_TestCase ), 'Monkey', true, + ENT_COMPAT, 'ISO-8859-1', array( "\nclass Monkey extends Mustache_Template", @@ -71,11 +72,32 @@ class Mustache_Test_CompilerTest extends PHPUnit_Framework_TestCase ), 'Monkey', false, + ENT_COMPAT, 'ISO-8859-1', array( "\nclass Monkey extends Mustache_Template", '$value = $this->resolveValue($context->find(\'name\'), $context, $indent);', - '$buffer .= $indent . htmlspecialchars($value, ENT_COMPAT, \'ISO-8859-1\');', + '$buffer .= $indent . htmlspecialchars($value, '.ENT_COMPAT.', \'ISO-8859-1\');', + 'return $buffer;', + ) + ), + + array( + '', + array( + array( + Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED, + Mustache_Tokenizer::NAME => 'name', + ) + ), + 'Monkey', + false, + ENT_QUOTES, + 'ISO-8859-1', + array( + "\nclass Monkey extends Mustache_Template", + '$value = $this->resolveValue($context->find(\'name\'), $context, $indent);', + '$buffer .= $indent . htmlspecialchars($value, '.ENT_QUOTES.', \'ISO-8859-1\');', 'return $buffer;', ) ), @@ -97,13 +119,14 @@ class Mustache_Test_CompilerTest extends PHPUnit_Framework_TestCase ), 'Monkey', false, + ENT_COMPAT, 'UTF-8', array( "\nclass Monkey extends Mustache_Template", '$buffer .= $indent . \'foo\'', '$buffer .= "\n"', '$value = $this->resolveValue($context->find(\'name\'), $context, $indent);', - '$buffer .= htmlspecialchars($value, ENT_COMPAT, \'UTF-8\');', + '$buffer .= htmlspecialchars($value, '.ENT_COMPAT.', \'UTF-8\');', '$value = $this->resolveValue($context->last(), $context, $indent);', '$buffer .= \'\\\'bar\\\'\';', 'return $buffer;',