diff --git a/library/Zend/Debug/Debug.php b/library/Zend/Debug/Debug.php index dd1472fba9f..fefae2b400e 100644 --- a/library/Zend/Debug/Debug.php +++ b/library/Zend/Debug/Debug.php @@ -10,6 +10,8 @@ namespace Zend\Debug; +use Zend\Escaper\Escaper; + /** * Concrete class for generating debug dumps related to the output source. * @@ -18,6 +20,10 @@ */ class Debug { + /** + * @var Escaper + */ + protected static $escaper = null; /** * @var string @@ -50,6 +56,31 @@ public static function setSapi($sapi) self::$sapi = $sapi; } + /** + * Set Escaper instance + * + * @param Escaper $escaper + */ + public static function setEscaper(Escaper $escaper) + { + static::$escaper = $escaper; + } + + /** + * Get Escaper instance + * + * Lazy loads an instance if none provided. + * + * @return Escaper + */ + public static function getEscaper() + { + if (null === static::$escaper) { + static::setEscaper(new Escaper()); + } + return static::$escaper; + } + /** * Debug helper function. This is a wrapper for var_dump() that adds * the
tags, cleans up newlines and indents, and runs @@ -78,7 +109,7 @@ public static function dump($var, $label=null, $echo=true) . PHP_EOL; } else { if (!extension_loaded('xdebug')) { - $output = htmlspecialchars($output, ENT_QUOTES); + $output = static::getEscaper()->escapeHtml($output); } $output = '' diff --git a/library/Zend/Debug/composer.json b/library/Zend/Debug/composer.json index 02b34458c47..de9d6bf8ccd 100644 --- a/library/Zend/Debug/composer.json +++ b/library/Zend/Debug/composer.json @@ -13,6 +13,10 @@ }, "target-dir": "Zend/Debug", "require": { - "php": ">=5.3.3" + "php": ">=5.3.3", + "zendframework/zend-escaper": "self.version" + }, + "suggest": { + "ext/xdebug": "XDebug, for better backtrace output" } -} \ No newline at end of file +} diff --git a/library/Zend/Feed/PubSubHubbub/PubSubHubbub.php b/library/Zend/Feed/PubSubHubbub/PubSubHubbub.php index 114f563b805..3e4b8ba3e8e 100644 --- a/library/Zend/Feed/PubSubHubbub/PubSubHubbub.php +++ b/library/Zend/Feed/PubSubHubbub/PubSubHubbub.php @@ -10,6 +10,7 @@ namespace Zend\Feed\PubSubHubbub; +use Zend\Escaper\Escaper; use Zend\Feed\Reader; use Zend\Http; @@ -32,10 +33,15 @@ class PubSubHubbub const SUBSCRIPTION_NOTVERIFIED = 'not_verified'; const SUBSCRIPTION_TODELETE = 'to_delete'; + /** + * @var Escaper + */ + protected static $escaper; + /** * Singleton instance if required of the HTTP client * - * @var \Zend\Http\Client + * @var Http\Client */ protected static $httpClient = null; @@ -67,7 +73,7 @@ public static function detectHubs($source) * Allows the external environment to make Zend_Oauth use a specific * Client instance. * - * @param \Zend\Http\Client $httpClient + * @param Http\Client $httpClient * @return void */ public static function setHttpClient(Http\Client $httpClient) @@ -80,15 +86,15 @@ public static function setHttpClient(Http\Client $httpClient) * the instance is reset and cleared of previous parameters GET/POST. * Headers are NOT reset but handled by this component if applicable. * - * @return \Zend\Http\Client + * @return Http\Client */ public static function getHttpClient() { - if (!isset(self::$httpClient)): + if (!isset(self::$httpClient)) { self::$httpClient = new Http\Client; - else: + } else { self::$httpClient->resetParameters(); - endif; + } return self::$httpClient; } @@ -103,6 +109,33 @@ public static function clearHttpClient() self::$httpClient = null; } + /** + * Set the Escaper instance + * + * If null, resets the instance + * + * @param null|Escaper $escaper + */ + public static function setEscaper(Escaper $escaper = null) + { + static::$escaper = $escaper; + } + + /** + * Get the Escaper instance + * + * If none registered, lazy-loads an instance. + * + * @return Escaper + */ + public static function getEscaper() + { + if (null === static::$escaper) { + static::setEscaper(new Escaper()); + } + return static::$escaper; + } + /** * RFC 3986 safe url encoding method * @@ -111,7 +144,8 @@ public static function clearHttpClient() */ public static function urlencode($string) { - $rawencoded = rawurlencode($string); + $escaper = static::getEscaper(); + $rawencoded = $escaper->escapeUrl($string); $rfcencoded = str_replace('%7E', '~', $rawencoded); return $rfcencoded; } diff --git a/library/Zend/Feed/composer.json b/library/Zend/Feed/composer.json index 61e61a53bf3..d98958ee8e9 100644 --- a/library/Zend/Feed/composer.json +++ b/library/Zend/Feed/composer.json @@ -14,6 +14,7 @@ "target-dir": "Zend/Feed", "require": { "php": ">=5.3.3", + "zendframework/zend-escaper": "self.version", "zendframework/zend-stdlib": "self.version" }, "suggest": { diff --git a/library/Zend/Log/Formatter/Xml.php b/library/Zend/Log/Formatter/Xml.php index 64bb6da200a..cbde6074c20 100644 --- a/library/Zend/Log/Formatter/Xml.php +++ b/library/Zend/Log/Formatter/Xml.php @@ -14,6 +14,7 @@ use DOMDocument; use DOMElement; use Traversable; +use Zend\Escaper\Escaper; use Zend\Stdlib\ArrayUtils; /** @@ -38,6 +39,11 @@ class Xml implements FormatterInterface */ protected $encoding; + /** + * @var Escaper instance + */ + protected $escaper; + /** * Format specifier for DateTime objects in event data (default: ISO 8601) * @@ -121,6 +127,33 @@ public function setEncoding($value) return $this; } + /** + * Set Escaper instance + * + * @param Escaper $escaper + * @return Xml + */ + public function setEscaper(Escaper $escaper) + { + $this->escaper = $escaper; + return $this; + } + + /** + * Get Escaper instance + * + * Lazy-loads an instance with the current encoding if none registered. + * + * @return Escaper + */ + public function getEscaper() + { + if (null === $this->escaper) { + $this->setEscaper(new Escaper($this->getEncoding())); + } + return $this->escaper; + } + /** * Formats data into a single line to be written by the writer. * @@ -142,9 +175,10 @@ public function format($event) } } - $enc = $this->getEncoding(); - $dom = new DOMDocument('1.0', $enc); - $elt = $dom->appendChild(new DOMElement($this->rootElement)); + $enc = $this->getEncoding(); + $escaper = $this->getEscaper(); + $dom = new DOMDocument('1.0', $enc); + $elt = $dom->appendChild(new DOMElement($this->rootElement)); foreach ($dataToInsert as $key => $value) { if (empty($value) @@ -152,7 +186,7 @@ public function format($event) || (is_object($value) && method_exists($value,'__toString')) ) { if ($key == "message") { - $value = htmlspecialchars($value, ENT_COMPAT, $enc); + $value = $escaper->escapeHtml($value); } elseif ($key == "extra" && empty($value)) { continue; } diff --git a/library/Zend/Log/composer.json b/library/Zend/Log/composer.json index 34c1fabc674..004d24beaf3 100644 --- a/library/Zend/Log/composer.json +++ b/library/Zend/Log/composer.json @@ -20,6 +20,7 @@ "suggest": { "ext-mongo": "*", "zendframework/zend-db": "Zend\\Db component", + "zendframework/zend-escaper": "Zend\\Escaper component, for use in the XML formatter", "zendframework/zend-mail": "Zend\\Mail component", "zendframework/zend-validator": "Zend\\Validator component" } diff --git a/library/Zend/Tag/Cloud/Decorator/AbstractCloud.php b/library/Zend/Tag/Cloud/Decorator/AbstractCloud.php index 956d2f07686..3c02ca1ad1a 100644 --- a/library/Zend/Tag/Cloud/Decorator/AbstractCloud.php +++ b/library/Zend/Tag/Cloud/Decorator/AbstractCloud.php @@ -10,62 +10,12 @@ namespace Zend\Tag\Cloud\Decorator; -use Traversable; -use Zend\Stdlib\ArrayUtils; -use Zend\Tag\Cloud\Decorator\DecoratorInterface as Decorator; - /** * Abstract class for cloud decorators * * @category Zend * @package Zend_Tag */ -abstract class AbstractCloud implements Decorator +abstract class AbstractCloud extends AbstractDecorator { - /** - * Option keys to skip when calling setOptions() - * - * @var array - */ - protected $skipOptions = array( - 'options', - 'config', - ); - - /** - * Create a new cloud decorator with options - * - * @param array|Traversable $options - */ - public function __construct($options = null) - { - if ($options instanceof Traversable) { - $options = ArrayUtils::iteratorToArray($options); - } - if (is_array($options)) { - $this->setOptions($options); - } - } - - /** - * Set options from array - * - * @param array $options Configuration for the decorator - * @return AbstractCloud - */ - public function setOptions(array $options) - { - foreach ($options as $key => $value) { - if (in_array(strtolower($key), $this->skipOptions)) { - continue; - } - - $method = 'set' . $key; - if (method_exists($this, $method)) { - $this->$method($value); - } - } - - return $this; - } } diff --git a/library/Zend/Tag/Cloud/Decorator/AbstractDecorator.php b/library/Zend/Tag/Cloud/Decorator/AbstractDecorator.php new file mode 100644 index 00000000000..4d6c9541268 --- /dev/null +++ b/library/Zend/Tag/Cloud/Decorator/AbstractDecorator.php @@ -0,0 +1,190 @@ +setOptions($options); + } + } + + /** + * Set options from array + * + * @param array $options Configuration for the decorator + * @return AbstractTag + */ + public function setOptions(array $options) + { + foreach ($options as $key => $value) { + if (in_array(strtolower($key), $this->skipOptions)) { + continue; + } + + $method = 'set' . $key; + if (method_exists($this, $method)) { + $this->$method($value); + } + } + + return $this; + } + + /** + * Get encoding + * + * @return string + */ + public function getEncoding() + { + return $this->encoding; + } + + /** + * Set encoding + * + * @param string + * @return HTMLCloud + */ + public function setEncoding($value) + { + $this->encoding = (string) $value; + return $this; + } + + /** + * Set Escaper instance + * + * @param Escaper $escaper + * @return HtmlCloud + */ + public function setEscaper($escaper) + { + $this->escaper = $escaper; + return $this; + } + + /** + * Retrieve Escaper instance + * + * If none registered, instantiates and registers one using current encoding. + * + * @return Escaper + */ + public function getEscaper() + { + if (null === $this->escaper) { + $this->setEscaper(new Escaper($this->getEncoding())); + } + return $this->escaper; + } + + /** + * Validate an HTML element name + * + * @param string $name + * @throws Exception\InvalidElementNameException + */ + protected function validateElementName($name) + { + if (!preg_match('/^[a-z0-9]+$/i', $name)) { + throw new Exception\InvalidElementNameException(sprintf( + '%s: Invalid element name "%s" provided; please provide valid HTML element names', + __METHOD__, + $this->getEscaper()->escapeHtml($name) + )); + } + } + + /** + * Validate an HTML attribute name + * + * @param string $name + * @throws Exception\InvalidAttributeNameException + */ + protected function validateAttributeName($name) + { + if (!preg_match('/^[a-z_:][-a-z0-9_:.]*$/i', $name)) { + throw new Exception\InvalidAttributeNameException(sprintf( + '%s: Invalid HTML attribute name "%s" provided; please provide valid HTML attribute names', + __METHOD__, + $this->getEscaper()->escapeHtml($name) + )); + } + } + + protected function wrapTag($html) + { + $escaper = $this->getEscaper(); + foreach ($this->getHTMLTags() as $key => $data) { + if (is_array($data)) { + $attributes = ''; + $htmlTag = $key; + $this->validateElementName($htmlTag); + + foreach ($data as $param => $value) { + $this->validateAttributeName($param); + $attributes .= ' ' . $param . '="' . $escaper->escapeHtmlAttr($value) . '"'; + } + } else { + $attributes = ''; + $htmlTag = $data; + $this->validateElementName($htmlTag); + } + + $html = sprintf('<%1$s%3$s>%2$s%1$s>', $htmlTag, $html, $attributes); + } + return $html; + } +} diff --git a/library/Zend/Tag/Cloud/Decorator/AbstractTag.php b/library/Zend/Tag/Cloud/Decorator/AbstractTag.php index ffd410b0e09..1db779289c0 100644 --- a/library/Zend/Tag/Cloud/Decorator/AbstractTag.php +++ b/library/Zend/Tag/Cloud/Decorator/AbstractTag.php @@ -10,62 +10,12 @@ namespace Zend\Tag\Cloud\Decorator; -use Traversable; -use Zend\Stdlib\ArrayUtils; -use Zend\Tag\Cloud\Decorator\DecoratorInterface as Decorator; - /** * Abstract class for tag decorators * * @category Zend * @package Zend_Tag */ -abstract class AbstractTag implements Decorator +abstract class AbstractTag extends AbstractDecorator { - /** - * Option keys to skip when calling setOptions() - * - * @var array - */ - protected $skipOptions = array( - 'options', - 'config', - ); - - /** - * Create a new cloud decorator with options - * - * @param array|Traversable $options - */ - public function __construct($options = null) - { - if ($options instanceof Traversable) { - $options = ArrayUtils::iteratorToArray($options); - } - if (is_array($options)) { - $this->setOptions($options); - } - } - - /** - * Set options from array - * - * @param array $options Configuration for the decorator - * @return AbstractTag - */ - public function setOptions(array $options) - { - foreach ($options as $key => $value) { - if (in_array(strtolower($key), $this->skipOptions)) { - continue; - } - - $method = 'set' . $key; - if (method_exists($this, $method)) { - $this->$method($value); - } - } - - return $this; - } } diff --git a/library/Zend/Tag/Cloud/Decorator/HtmlCloud.php b/library/Zend/Tag/Cloud/Decorator/HtmlCloud.php index b0429469563..f352033dee9 100644 --- a/library/Zend/Tag/Cloud/Decorator/HtmlCloud.php +++ b/library/Zend/Tag/Cloud/Decorator/HtmlCloud.php @@ -18,11 +18,6 @@ */ class HtmlCloud extends AbstractCloud { - /** - * @var string Encoding to use - */ - protected $encoding = 'UTF-8'; - /** * List of HTML tags * @@ -39,28 +34,6 @@ class HtmlCloud extends AbstractCloud */ protected $separator = ' '; - /** - * Get encoding - * - * @return string - */ - public function getEncoding() - { - return $this->encoding; - } - - /** - * Set encoding - * - * @param string - * @return HTMLCloud - */ - public function setEncoding($value) - { - $this->encoding = (string) $value; - return $this; - } - /** * Set the HTML tags surrounding all tags * @@ -121,24 +94,7 @@ public function render($tags) )); } $cloudHTML = implode($this->getSeparator(), $tags); - - $enc = $this->getEncoding(); - foreach ($this->getHTMLTags() as $key => $data) { - if (is_array($data)) { - $htmlTag = $key; - $attributes = ''; - - foreach ($data as $param => $value) { - $attributes .= ' ' . $param . '="' . htmlspecialchars($value, ENT_COMPAT, $enc) . '"'; - } - } else { - $htmlTag = $data; - $attributes = ''; - } - - $cloudHTML = sprintf('<%1$s%3$s>%2$s%1$s>', $htmlTag, $cloudHTML, $attributes); - } - + $cloudHTML = $this->wrapTag($cloudHTML); return $cloudHTML; } } diff --git a/library/Zend/Tag/Cloud/Decorator/HtmlTag.php b/library/Zend/Tag/Cloud/Decorator/HtmlTag.php index de8b9a2e4d2..70327af0c95 100644 --- a/library/Zend/Tag/Cloud/Decorator/HtmlTag.php +++ b/library/Zend/Tag/Cloud/Decorator/HtmlTag.php @@ -29,11 +29,6 @@ class HtmlTag extends AbstractTag */ protected $classList = null; - /** - * @var string Encoding to utilize - */ - protected $encoding = 'UTF-8'; - /** * Unit for the fontsize * @@ -107,28 +102,6 @@ public function getClassList() return $this->classList; } - /** - * Get encoding - * - * @return string - */ - public function getEncoding() - { - return $this->encoding; - } - - /** - * Set encoding - * - * @param string $value - * @return HTMLTag - */ - public function setEncoding($value) - { - $this->encoding = (string) $value; - return $this; - } - /** * Set the font size unit * @@ -259,32 +232,16 @@ public function render($tags) $result = array(); - $enc = $this->getEncoding(); + $escaper = $this->getEscaper(); foreach ($tags as $tag) { if (null === ($classList = $this->getClassList())) { $attribute = sprintf('style="font-size: %d%s;"', $tag->getParam('weightValue'), $this->getFontSizeUnit()); } else { - $attribute = sprintf('class="%s"', htmlspecialchars($tag->getParam('weightValue'), ENT_COMPAT, $enc)); - } - - $tagHTML = sprintf('%s', htmlSpecialChars($tag->getParam('url'), ENT_COMPAT, $enc), $attribute, $tag->getTitle()); - - foreach ($this->getHTMLTags() as $key => $data) { - if (is_array($data)) { - $htmlTag = $key; - $attributes = ''; - - foreach ($data as $param => $value) { - $attributes .= ' ' . $param . '="' . htmlspecialchars($value, ENT_COMPAT, $enc) . '"'; - } - } else { - $htmlTag = $data; - $attributes = ''; - } - - $tagHTML = sprintf('<%1$s%3$s>%2$s%1$s>', $htmlTag, $tagHTML, $attributes); + $attribute = sprintf('class="%s"', $escaper->escapeHtmlAttr($tag->getParam('weightValue'))); } + $tagHTML = sprintf('%s', $escaper->escapeHtml($tag->getParam('url')), $attribute, $escaper->escapeHtml($tag->getTitle())); + $tagHTML = $this->wrapTag($tagHTML); $result[] = $tagHTML; } diff --git a/library/Zend/Tag/Exception/InvalidAttributeNameException.php b/library/Zend/Tag/Exception/InvalidAttributeNameException.php new file mode 100644 index 00000000000..41288292adc --- /dev/null +++ b/library/Zend/Tag/Exception/InvalidAttributeNameException.php @@ -0,0 +1,16 @@ +=5.3.3" + "php": ">=5.3.3", + "zendframework/zend-escaper": "self.version" } -} \ No newline at end of file +} diff --git a/library/Zend/Uri/Uri.php b/library/Zend/Uri/Uri.php index 6e700c8fc2a..4dfa5224f5e 100644 --- a/library/Zend/Uri/Uri.php +++ b/library/Zend/Uri/Uri.php @@ -10,6 +10,7 @@ namespace Zend\Uri; +use Zend\Escaper\Escaper; use Zend\Validator; /** @@ -125,6 +126,11 @@ class Uri implements UriInterface */ protected static $defaultPorts = array(); + /** + * @var Escaper + */ + protected static $escaper; + /** * Create a new URI object * @@ -152,6 +158,31 @@ public function __construct($uri = null) } } + /** + * Set Escaper instance + * + * @param Escaper $escaper + */ + public static function setEscaper(Escaper $escaper) + { + static::$escaper = $escaper; + } + + /** + * Retrieve Escaper instance + * + * Lazy-loads one if none provided + * + * @return Escaper + */ + public static function getEscaper() + { + if (null === static::$escaper) { + static::setEscaper(new Escaper()); + } + return static::$escaper; + } + /** * Check if the URI is valid * @@ -935,8 +966,9 @@ public static function encodeUserInfo($userInfo) } $regex = '/(?:[^' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . '%:]|%(?![A-Fa-f0-9]{2}))/'; - $replace = function($match) { - return rawurlencode($match[0]); + $escaper = static::getEscaper(); + $replace = function ($match) use ($escaper) { + return $escaper->escapeUrl($match[0]); }; return preg_replace_callback($regex, $replace, $userInfo); @@ -962,8 +994,9 @@ public static function encodePath($path) } $regex = '/(?:[^' . self::CHAR_UNRESERVED . ':@&=\+\$,\/;%]+|%(?![A-Fa-f0-9]{2}))/'; - $replace = function($match) { - return rawurlencode($match[0]); + $escaper = static::getEscaper(); + $replace = function ($match) use ($escaper) { + return $escaper->escapeUrl($match[0]); }; return preg_replace_callback($regex, $replace, $path); @@ -990,8 +1023,9 @@ public static function encodeQueryFragment($input) } $regex = '/(?:[^' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . '%:@\/\?]+|%(?![A-Fa-f0-9]{2}))/'; - $replace = function($match) { - return rawurlencode($match[0]); + $escaper = static::getEscaper(); + $replace = function ($match) use ($escaper) { + return $escaper->escapeUrl($match[0]); }; return preg_replace_callback($regex, $replace, $input); diff --git a/library/Zend/Uri/composer.json b/library/Zend/Uri/composer.json index 52fd0a34967..ae5e2cbcf3c 100644 --- a/library/Zend/Uri/composer.json +++ b/library/Zend/Uri/composer.json @@ -14,6 +14,7 @@ "target-dir": "Zend/Uri", "require": { "php": ">=5.3.3", + "zendframework/zend-escaper": "self.version", "zendframework/zend-validator": "self.version" } -} \ No newline at end of file +} diff --git a/library/Zend/View/Helper/HeadStyle.php b/library/Zend/View/Helper/HeadStyle.php index 5a400b76e87..369dd99fc7a 100644 --- a/library/Zend/View/Helper/HeadStyle.php +++ b/library/Zend/View/Helper/HeadStyle.php @@ -311,6 +311,7 @@ public function itemToString(stdClass $item, $indent) ) { $enc = $this->view->getEncoding(); } + $escaper = $this->getEscaper($enc); foreach ($item->attributes as $key => $value) { if (!in_array($key, $this->optionalAttributes)) { continue; @@ -333,7 +334,7 @@ public function itemToString(stdClass $item, $indent) $value = substr($value, 0, -1); } } - $attrString .= sprintf(' %s="%s"', $key, htmlspecialchars($value, ENT_COMPAT, $enc)); + $attrString .= sprintf(' %s="%s"', $key, $escaper->escapeHtmlAttr($value)); } } diff --git a/library/Zend/View/Helper/Navigation/Sitemap.php b/library/Zend/View/Helper/Navigation/Sitemap.php index 37da30f51f5..f55d4d5ccad 100644 --- a/library/Zend/View/Helper/Navigation/Sitemap.php +++ b/library/Zend/View/Helper/Navigation/Sitemap.php @@ -242,14 +242,8 @@ public function getServerUrl() */ protected function xmlEscape($string) { - $enc = 'UTF-8'; - if ($this->view instanceof View\Renderer\RendererInterface - && method_exists($this->view, 'getEncoding') - ) { - $enc = $this->view->getEncoding(); - } - - return htmlspecialchars($string, ENT_QUOTES, $enc, false); + $escaper = $this->view->plugin('escapeHtml'); + return $escaper($string); } // Public methods: diff --git a/library/Zend/View/Helper/Placeholder/Container/AbstractStandalone.php b/library/Zend/View/Helper/Placeholder/Container/AbstractStandalone.php index 8017f516113..61ba616f2a2 100644 --- a/library/Zend/View/Helper/Placeholder/Container/AbstractStandalone.php +++ b/library/Zend/View/Helper/Placeholder/Container/AbstractStandalone.php @@ -10,8 +10,10 @@ namespace Zend\View\Helper\Placeholder\Container; +use Zend\Escaper\Escaper; use Zend\View\Exception; use Zend\View\Helper\Placeholder\Registry; +use Zend\View\Renderer\RendererInterface; /** * Base class for targeted placeholder helpers @@ -28,6 +30,11 @@ abstract class AbstractStandalone */ protected $container; + /** + * @var Escaper[] + */ + protected $escapers = array(); + /** * @var \Zend\View\Helper\Placeholder\Registry */ @@ -78,6 +85,35 @@ public function setRegistry(Registry $registry) return $this; } + /** + * Set Escaper instance + * + * @param Escaper $escaper + * @return AbstractStandalone + */ + public function setEscaper(Escaper $escaper) + { + $encoding = $escaper->getEncoding(); + $this->escapers[$encoding] = $escaper; + return $this; + } + + /** + * Get Escaper instance + * + * Lazy-loads one if none available + * + * @return mixed + */ + public function getEscaper($enc = 'UTF-8') + { + $enc = strtolower($enc); + if (!isset($this->escapers[$enc])) { + $this->setEscaper(new Escaper($enc)); + } + return $this->escapers[$enc]; + } + /** * Set whether or not auto escaping should be used * @@ -108,23 +144,16 @@ public function getAutoEscape() */ protected function escape($string) { - $enc = 'UTF-8'; - if ($this->view instanceof \Zend\View\Renderer\RendererInterface + if ($this->view instanceof RendererInterface && method_exists($this->view, 'getEncoding') ) { - $enc = $this->view->getEncoding(); + $enc = $this->view->getEncoding(); $escaper = $this->view->plugin('escapeHtml'); return $escaper((string) $string); } - /** - * bump this out to a protected method to kill the instance penalty! - */ - $escaper = new \Zend\Escaper\Escaper($enc); + + $escaper = $this->getEscaper(); return $escaper->escapeHtml((string) $string); - /** - * Replaced to ensure consistent escaping - */ - //return htmlspecialchars((string) $string, ENT_COMPAT, $enc); } /** diff --git a/tests/ZendTest/Tag/Cloud/CloudTest.php b/tests/ZendTest/Tag/Cloud/CloudTest.php index b22690bb6a9..0b8b07438bc 100644 --- a/tests/ZendTest/Tag/Cloud/CloudTest.php +++ b/tests/ZendTest/Tag/Cloud/CloudTest.php @@ -208,7 +208,7 @@ public function testSkipOptions() public function testRender() { $cloud = $this->_getCloud(array('tags' => array(array('title' => 'foo', 'weight' => 1), array('title' => 'bar', 'weight' => 3)))); - $expected = '