Explorar el Código

ZF-8715: Fix encoding issues for all components that escape data using htmlentities and/or htmlspecialchars; set default character set to UTF-8

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@20104 44c647ce-9c0f-0410-b52a-842ac1e357ba
matthew hace 16 años
padre
commit
e59672084c

+ 6 - 1
library/Zend/Dojo/View/Helper/Dojo/Container.php

@@ -1089,11 +1089,16 @@ EOJ;
             return '';
         }
 
+        $enc = 'UTF-8';
+        if ($this->view instanceof Zend_View_Abstract) {
+            $enc = $this->view->getEncoding();
+        }
+
         $html = array();
         foreach ($layers as $path) {
             $html[] = sprintf(
                 '<script type="text/javascript" src="%s"></script>',
-                htmlentities($path, ENT_QUOTES)
+                htmlspecialchars($path, ENT_QUOTES, $enc)
             );
         }
 

+ 28 - 2
library/Zend/Feed/Element.php

@@ -38,6 +38,11 @@ class Zend_Feed_Element implements ArrayAccess
     protected $_element;
 
     /**
+     * @var string Character encoding to utilize
+     */
+    protected $_encoding = 'UTF-8';
+
+    /**
      * @var Zend_Feed_Element
      */
     protected $_parentElement;
@@ -148,6 +153,27 @@ class Zend_Feed_Element implements ArrayAccess
         return $this->_element->ownerDocument->saveXML($this->_element);
     }
 
+    /**
+     * Get encoding
+     *
+     * @return string
+     */
+    public function getEncoding()
+    {
+        return $this->_encoding;
+    }
+
+    /**
+     * Set encoding
+     *
+     * @param  string $value Encoding to use
+     * @return Zend_Feed_Element
+     */
+    public function setEncoding($value)
+    {
+        $this->_encoding = (string) $value;
+        return $this;
+    }
 
     /**
      * Map variable access onto the underlying entry representation.
@@ -205,11 +231,11 @@ class Zend_Feed_Element implements ArrayAccess
             if (strpos($var, ':') !== false) {
                 list($ns, $elt) = explode(':', $var, 2);
                 $node = $this->_element->ownerDocument->createElementNS(Zend_Feed::lookupNamespace($ns),
-                    $var, htmlspecialchars($val, ENT_NOQUOTES, 'UTF-8'));
+                    $var, htmlspecialchars($val, ENT_NOQUOTES, $this->getEncoding()));
                 $this->_element->appendChild($node);
             } else {
                 $node = $this->_element->ownerDocument->createElement($var,
-                    htmlspecialchars($val, ENT_NOQUOTES, 'UTF-8'));
+                    htmlspecialchars($val, ENT_NOQUOTES, $this->getEncoding()));
                 $this->_element->appendChild($node);
             }
         } elseif (count($nodes) > 1) {

+ 37 - 8
library/Zend/Filter/HtmlEntities.php

@@ -44,7 +44,7 @@ class Zend_Filter_HtmlEntities implements Zend_Filter_Interface
      *
      * @var string
      */
-    protected $_charSet;
+    protected $_encoding;
 
     /**
      * Corresponds to the forth htmlentities() argument
@@ -76,8 +76,11 @@ class Zend_Filter_HtmlEntities implements Zend_Filter_Interface
             $options['quotestyle'] = ENT_COMPAT;
         }
 
-        if (!isset($options['charset'])) {
-            $options['charset'] = 'ISO-8859-1';
+        if (!isset($options['encoding'])) {
+            $options['encoding'] = 'UTF-8';
+        }
+        if (isset($options['charset'])) {
+            $options['encoding'] = $options['charset'];
         }
 
         if (!isset($options['doublequote'])) {
@@ -85,7 +88,7 @@ class Zend_Filter_HtmlEntities implements Zend_Filter_Interface
         }
 
         $this->setQuoteStyle($options['quotestyle']);
-        $this->setCharSet($options['charset']);
+        $this->setEncoding($options['encoding']);
         $this->setDoubleQuote($options['doublequote']);
     }
 
@@ -111,26 +114,52 @@ class Zend_Filter_HtmlEntities implements Zend_Filter_Interface
         return $this;
     }
 
+
+    /**
+     * Get encoding
+     *
+     * @return string
+     */
+    public function getEncoding()
+    {
+         return $this->_encoding;
+    }
+
+    /**
+     * Set encoding
+     *
+     * @param  string $value
+     * @return Zend_Filter_HtmlEntities
+     */
+    public function setEncoding($value)
+    {
+        $this->_encoding = (string) $value;
+        return $this;
+    }
+
     /**
      * Returns the charSet option
      *
+     * Proxies to {@link getEncoding()}
+     *
      * @return string
      */
     public function getCharSet()
     {
-        return $this->_charSet;
+        return $this->getEncoding();
     }
 
     /**
      * Sets the charSet option
      *
+     * Proxies to {@link setEncoding()}
+     *
      * @param  string $charSet
      * @return Zend_Filter_HtmlEntities Provides a fluent interface
      */
     public function setCharSet($charSet)
     {
-        $this->_charSet = $charSet;
-        return $this;
+        return $this->setEncoding($charSet);
     }
 
     /**
@@ -166,6 +195,6 @@ class Zend_Filter_HtmlEntities implements Zend_Filter_Interface
      */
     public function filter($value)
     {
-        return htmlentities((string) $value, $this->_quoteStyle, $this->_charSet, $this->_doubleQuote);
+        return htmlentities((string) $value, $this->getQuoteStyle(), $this->getEncoding(), $this->getDoubleQuote());
     }
 }

+ 34 - 2
library/Zend/Form/Decorator/HtmlTag.php

@@ -50,6 +50,12 @@ require_once 'Zend/Form/Decorator/Abstract.php';
 class Zend_Form_Decorator_HtmlTag extends Zend_Form_Decorator_Abstract
 {
     /**
+     * Character encoding to use when escaping attributes
+     * @var string
+     */
+    protected $_encoding;
+
+    /**
      * Placement; default to surround content
      * @var string
      */
@@ -74,12 +80,13 @@ class Zend_Form_Decorator_HtmlTag extends Zend_Form_Decorator_Abstract
     protected function _htmlAttribs(array $attribs)
     {
         $xhtml = '';
+        $enc   = $this->_getEncoding();
         foreach ((array) $attribs as $key => $val) {
-            $key = htmlspecialchars($key, ENT_COMPAT, 'UTF-8');
+            $key = htmlspecialchars($key, ENT_COMPAT, $enc);
             if (is_array($val)) {
                 $val = implode(' ', $val);
             }
-            $val    = htmlspecialchars($val, ENT_COMPAT, 'UTF-8');
+            $val    = htmlspecialchars($val, ENT_COMPAT, $enc);
             $xhtml .= " $key=\"$val\"";
         }
         return $xhtml;
@@ -216,4 +223,29 @@ class Zend_Form_Decorator_HtmlTag extends Zend_Form_Decorator_Abstract
                      . (($closeOnly || !$openOnly) ? $this->_getCloseTag($tag) : '');
         }
     }
+
+    /**
+     * Get encoding for use with htmlspecialchars()
+     * 
+     * @return string
+     */
+    protected function _getEncoding()
+    {
+        if (null !== $this->_encoding) {
+            return $this->_encoding;
+        }
+
+        if (null === ($element = $this->getElement())) {
+            $this->_encoding = 'UTF-8';
+        } elseif (null === ($view = $element->getView())) {
+            $this->_encoding = 'UTF-8';
+        } elseif (!$view instanceof Zend_View_Abstract
+            && !method_exists($view, 'getEncoding')
+        ) {
+            $this->_encoding = 'UTF-8';
+        } else {
+            $this->_encoding = $view->getEncoding();
+        }
+        return $this->_encoding;
+    }
 }

+ 34 - 3
library/Zend/Log/Formatter/Xml.php

@@ -44,14 +44,44 @@ class Zend_Log_Formatter_Xml implements Zend_Log_Formatter_Interface
     protected $_elementMap;
 
     /**
+     * @var string Encoding to use in XML
+     */
+    protected $_encoding;
+
+    /**
      * Class constructor
      *
+     * @param string $rootElement Name of root element
      * @param array $elementMap
+     * @param string $encoding Encoding to use (defaults to UTF-8)
      */
-    public function __construct($rootElement = 'logEntry', $elementMap = null)
+    public function __construct($rootElement = 'logEntry', $elementMap = null, $encoding = 'UTF-8')
     {
         $this->_rootElement = $rootElement;
         $this->_elementMap  = $elementMap;
+        $this->setEncoding($encoding);
+    }
+
+    /**
+     * Get encoding
+     *
+     * @return string
+     */
+    public function getEncoding()
+    {
+        return $this->_encoding;
+    }
+
+    /**
+     * Set encoding
+     *
+     * @param  string $value
+     * @return Zend_Log_Formatter_Xml
+     */
+    public function setEncoding($value)
+    {
+        $this->_encoding = (string) $value;
+        return $this;
     }
 
     /**
@@ -71,12 +101,13 @@ class Zend_Log_Formatter_Xml implements Zend_Log_Formatter_Interface
             }
         }
 
-        $dom = new DOMDocument();
+        $enc = $this->getEncoding();
+        $dom = new DOMDocument('1.0', $enc);
         $elt = $dom->appendChild(new DOMElement($this->_rootElement));
 
         foreach ($dataToInsert as $key => $value) {
             if($key == "message") {
-                $value = htmlspecialchars($value);
+                $value = htmlspecialchars($value, ENT_COMPAT, $enc);
             }
             $elt->appendChild(new DOMElement($key, $value));
         }

+ 29 - 1
library/Zend/Tag/Cloud/Decorator/HtmlCloud.php

@@ -37,6 +37,11 @@ require_once 'Zend/Tag/Cloud/Decorator/Cloud.php';
 class Zend_Tag_Cloud_Decorator_HtmlCloud extends Zend_Tag_Cloud_Decorator_Cloud
 {
     /**
+     * @var string Encoding to use
+     */
+    protected $_encoding = 'UTF-8';
+
+    /**
      * List of HTML tags
      *
      * @var array
@@ -53,6 +58,28 @@ class Zend_Tag_Cloud_Decorator_HtmlCloud extends Zend_Tag_Cloud_Decorator_Cloud
     protected $_separator = ' ';
 
     /**
+     * Get encoding
+     *
+     * @return string
+     */
+    public function getEncoding()
+    {
+        return $this->_encoding;
+    }
+
+    /**
+     * Set encoding
+     *
+     * @param string
+     * @return Zend_Tag_Cloud_Decorator_HtmlCloud
+     */
+    public function setEncoding($value)
+    {
+        $this->_encoding = (string) $value;
+        return $this;
+    }
+
+    /**
      * Set the HTML tags surrounding all tags
      *
      * @param  array $htmlTags
@@ -106,13 +133,14 @@ class Zend_Tag_Cloud_Decorator_HtmlCloud extends Zend_Tag_Cloud_Decorator_Cloud
     {
         $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) . '"';
+                    $attributes .= ' ' . $param . '="' . htmlspecialchars($value, ENT_COMPAT, $enc) . '"';
                 }
             } else {
                 $htmlTag    = $data;

+ 31 - 3
library/Zend/Tag/Cloud/Decorator/HtmlTag.php

@@ -45,6 +45,11 @@ class Zend_Tag_Cloud_Decorator_HtmlTag extends Zend_Tag_Cloud_Decorator_Tag
     protected $_classList = null;
 
     /**
+     * @var string Encoding to utilize
+     */
+    protected $_encoding = 'UTF-8';
+
+    /**
      * Unit for the fontsize
      *
      * @var string
@@ -120,6 +125,28 @@ class Zend_Tag_Cloud_Decorator_HtmlTag extends Zend_Tag_Cloud_Decorator_Tag
     }
 
     /**
+     * Get encoding
+     *
+     * @return string
+     */
+    public function getEncoding()
+    {
+         return $this->_encoding;
+    }
+
+    /**
+     * Set encoding
+     *
+     * @param  string $value
+     * @return Zend_Tag_Cloud_Decorator_HtmlTag
+     */
+    public function setEncoding($value)
+    {
+        $this->_encoding = (string) $value;
+        return $this;
+    }
+
+    /**
      * Set the font size unit
      *
      * Possible values are: em, ex, px, in, cm, mm, pt, pc and %
@@ -245,14 +272,15 @@ class Zend_Tag_Cloud_Decorator_HtmlTag extends Zend_Tag_Cloud_Decorator_Tag
 
         $result = array();
 
+        $enc = $this->getEncoding();
         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')));
+                $attribute = sprintf('class="%s"', htmlspecialchars($tag->getParam('weightValue'), ENT_COMPAT, $enc));
             }
 
-            $tagHtml = sprintf('<a href="%s" %s>%s</a>', htmlSpecialChars($tag->getParam('url')), $attribute, $tag->getTitle());
+            $tagHtml = sprintf('<a href="%s" %s>%s</a>', htmlSpecialChars($tag->getParam('url'), ENT_COMPAT, $enc), $attribute, $tag->getTitle());
 
             foreach ($this->getHtmlTags() as $key => $data) {
                 if (is_array($data)) {
@@ -260,7 +288,7 @@ class Zend_Tag_Cloud_Decorator_HtmlTag extends Zend_Tag_Cloud_Decorator_Tag
                     $attributes = '';
 
                     foreach ($data as $param => $value) {
-                        $attributes .= ' ' . $param . '="' . htmlspecialchars($value) . '"';
+                        $attributes .= ' ' . $param . '="' . htmlspecialchars($value, ENT_COMPAT, $enc) . '"';
                     }
                 } else {
                     $htmlTag    = $data;

+ 2 - 2
library/Zend/View/Abstract.php

@@ -109,10 +109,10 @@ abstract class Zend_View_Abstract implements Zend_View_Interface
     private $_escape = 'htmlspecialchars';
 
     /**
-     * Encoding to use in escaping mechanisms; defaults to latin1 (ISO-8859-1)
+     * Encoding to use in escaping mechanisms; defaults to utf-8
      * @var string
      */
-    private $_encoding = 'ISO-8859-1';
+    private $_encoding = 'UTF-8';
 
     /**
      * Flag indicating whether or not LFI protection for rendering view scripts is enabled

+ 7 - 1
library/Zend/View/Helper/HeadStyle.php

@@ -323,6 +323,12 @@ class Zend_View_Helper_HeadStyle extends Zend_View_Helper_Placeholder_Container_
     {
         $attrString = '';
         if (!empty($item->attributes)) {
+            $enc = 'UTF-8';
+            if ($this->view instanceof Zend_View_Interface
+                && method_exists($this->view, 'getEncoding')
+            ) {
+                $enc = $this->view->getEncoding();
+            }
             foreach ($item->attributes as $key => $value) {
                 if (!in_array($key, $this->_optionalAttributes)) {
                     continue;
@@ -345,7 +351,7 @@ class Zend_View_Helper_HeadStyle extends Zend_View_Helper_Placeholder_Container_
                         $value = substr($value, 0, -1);
                     }
                 }
-                $attrString .= sprintf(' %s="%s"', $key, htmlspecialchars($value));
+                $attrString .= sprintf(' %s="%s"', $key, htmlspecialchars($value, ENT_COMPAT, $enc));
             }
         }
 

+ 8 - 1
library/Zend/View/Helper/Navigation/Sitemap.php

@@ -262,10 +262,17 @@ class Zend_View_Helper_Navigation_Sitemap
      */
     protected function _xmlEscape($string)
     {
+        $enc = 'UTF-8';
+        if ($this->view instanceof Zend_View_Interface
+            && method_exists($this->view, 'getEncoding')
+        ) {
+            $enc = $this->view->getEncoding();
+        }
+
         // TODO: remove check when minimum PHP version is >= 5.2.3
         if (version_compare(PHP_VERSION, '5.2.3', '>=')) {
             // do not encode existing HTML entities
-            return htmlspecialchars($string, ENT_QUOTES, 'UTF-8', false);
+            return htmlspecialchars($string, ENT_QUOTES, $enc, false);
         } else {
             $string = preg_replace('/&(?!(?:#\d++|[a-z]++);)/ui', '&amp;', $string);
             $string = str_replace(array('<', '>', '\'', '"'), array('&lt;', '&gt;', '&#39;', '&quot;'), $string);

+ 2 - 1
tests/Zend/Filter/HtmlEntitiesTest.php

@@ -101,11 +101,12 @@ class Zend_Filter_HtmlEntitiesTest extends PHPUnit_Framework_TestCase
     /**
      * Ensures that getCharSet() returns expected default value
      *
+     * @group ZF-8715
      * @return void
      */
     public function testGetCharSet()
     {
-        $this->assertEquals('ISO-8859-1', $this->_filter->getCharSet());
+        $this->assertEquals('UTF-8', $this->_filter->getCharSet());
     }
 
     /**

+ 1 - 0
tests/Zend/Tag/Cloud/Decorator/HtmlTagTest.php

@@ -32,6 +32,7 @@ require_once dirname(__FILE__) . '/../../../../TestHelper.php';
 require_once 'Zend/Tag/Item.php';
 require_once 'Zend/Tag/ItemList.php';
 require_once 'Zend/Tag/Cloud/Decorator/HtmlTag.php';
+require_once 'Zend/Config.php';
 
 /**
  * @category   Zend

+ 4 - 3
tests/Zend/ViewTest.php

@@ -451,14 +451,15 @@ class Zend_ViewTest extends PHPUnit_Framework_TestCase
 
     /**
      * Test set/getEncoding()
+     * @group ZF-8715
      */
     public function testSetGetEncoding()
     {
         $view = new Zend_View();
-        $this->assertEquals('ISO-8859-1', $view->getEncoding());
-
-        $view->setEncoding('UTF-8');
         $this->assertEquals('UTF-8', $view->getEncoding());
+
+        $view->setEncoding('ISO-8859-1');
+        $this->assertEquals('ISO-8859-1', $view->getEncoding());
     }
 
     public function testEmptyPropertiesReturnAppropriately()