From 948dece70712272df5552e1651bbc795199a9a62 Mon Sep 17 00:00:00 2001 From: Maks3w Date: Thu, 12 Jul 2012 21:11:36 +0200 Subject: [PATCH 1/4] [PSR-2] fixers=braces,elseif,short_tag,php_closing_tag,trailing_spaces,linefeed Applied php-cs-fixer --fixers=braces,elseif,short_tag,php_closing_tag,trailing_spaces,linefeed --- src/Escaper.php | 40 ++++++++++++++++++++-------------------- test/EscaperTest.php | 12 ++++++------ 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/Escaper.php b/src/Escaper.php index 42940a9..ea0012f 100644 --- a/src/Escaper.php +++ b/src/Escaper.php @@ -23,7 +23,7 @@ class Escaper /** * Current encoding for escaping. If not UTF-8, we convert strings from this encoding * pre-escaping and back to this encoding post-escaping. - * + * * @var string */ protected $encoding = 'utf-8'; @@ -33,35 +33,35 @@ class Escaper * htmlspecialchars(). We modify these for PHP 5.4 to take advantage * of the new ENT_SUBSTITUTE flag for correctly dealing with invalid * UTF-8 sequences. - * + * * @var string */ protected $htmlSpecialCharsFlags = ENT_QUOTES; /** * Static Matcher which escapes characters for HTML Attribute contexts - * + * * @var Closure */ protected $htmlAttrMatcher = null; /** * Static Matcher which escapes characters for Javascript contexts - * + * * @var Closure */ protected $jsMatcher = null; /** * Static Matcher which escapes characters for CSS Attribute contexts - * + * * @var Closure */ protected $cssMatcher = null; /** * List of all encoding supported by this class - * + * * @var array */ protected $supportedEncodings = array( @@ -80,7 +80,7 @@ class Escaper * Constructor: Single parameter allows setting of global encoding for use by * the current object. If PHP 5.4 is detected, additional ENT_SUBSTITUTE flag * is set for htmlspecialchars() calls. - * + * * @param string $encoding */ public function __construct($encoding = null) @@ -107,7 +107,7 @@ public function __construct($encoding = null) /** * Return the encoding that all output/input is expected to be encoded in. - * + * * @return string */ public function getEncoding() @@ -118,7 +118,7 @@ public function getEncoding() /** * Escape a string for the HTML Body context where there are very few characters * of special meaning. Internally this will use htmlspecialchars(). - * + * * @param string $string * @return string */ @@ -132,7 +132,7 @@ public function escapeHtml($string) * Escape a string for the HTML Attribute context. We use an extended set of characters * to escape that are not covered by htmlspecialchars() to cover cases where an attribute * might be unquoted or quoted illegally (e.g. backticks are valid quotes for IE). - * + * * @param string $string * @return string */ @@ -158,7 +158,7 @@ public function escapeHtmlAttr($string) * of cases where HTML escaping was not applied on top of Javascript escaping correctly. * Backslash escaping is not used as it still leaves the escaped character as-is and so * is not useful in a HTML context. - * + * * @param string $string * @return string */ @@ -180,7 +180,7 @@ public function escapeJs($string) * Escape a string for the URI or Parameter contexts. This should not be used to escape * an entire URI - only a subcomponent being inserted. The function is a simple proxy * to rawurlencode() which now implements RFC 3986 since PHP 5.3 completely. - * + * * @param string $string * @return string */ @@ -192,7 +192,7 @@ public function escapeUrl($string) /** * Escape a string for the CSS context. CSS escaping can be applied to any string being * inserted into CSS and escapes everything except alphanumerics. - * + * * @param string $string * @return string */ @@ -213,7 +213,7 @@ public function escapeCss($string) /** * Callback function for preg_replace_callback that applies HTML Attribute * escaping to all matches. - * + * * @param array $matches * @return string */ @@ -253,7 +253,7 @@ public function htmlAttrMatcher($matches) /** * Callback function for preg_replace_callback that applies Javascript * escaping to all matches. - * + * * @param array $matches * @return string */ @@ -271,7 +271,7 @@ public function jsMatcher($matches) /** * Callback function for preg_replace_callback that applies CSS * escaping to all matches. - * + * * @param array $matches * @return string */ @@ -291,7 +291,7 @@ public function cssMatcher($matches) /** * Converts a string to UTF-8 from the base encoding. The base encoding is set via this * class' constructor. - * + * * @param string $string * @return string */ @@ -326,7 +326,7 @@ protected function fromUtf8($string) /** * Checks if a given string appears to be valid UTF-8 or not. - * + * * @param string $string * @return bool */ @@ -343,7 +343,7 @@ protected function isUtf8($string) /** * Encoding conversion helper which wraps iconv and mbstring where they exist or throws * and exception where neither is available. - * + * * @param string $string * @return string */ @@ -375,7 +375,7 @@ protected function convertEncoding($string, $to, $from) * has become HTML5's XML Serialisation which is restricted to the those named * entities that XML supports. Using HTML entities would result in this error: * XML Parsing Error: undefined entity - * + * * @var array */ protected $htmlNamedEntityMap = array( diff --git a/test/EscaperTest.php b/test/EscaperTest.php index 49256d5..7cbee2d 100644 --- a/test/EscaperTest.php +++ b/test/EscaperTest.php @@ -164,7 +164,7 @@ class EscaperTest extends \PHPUnit_Framework_TestCase /* Encode spaces for quoteless attribute protection */ ' ' => '\\20 ', ); - + public function setUp() { @@ -263,7 +263,7 @@ public function testUrlEscapingConvertsSpecialChars() * Range tests to confirm escaped range of characters is within OWASP recommendation */ - /** + /** * Only testing the first few 2 ranges on this prot. function as that's all these * other range tests require */ @@ -280,7 +280,7 @@ public function testUnicodeCodepointConversionToUtf8() /** * Convert a Unicode Codepoint to a literal UTF-8 character. - * + * * @param int Unicode codepoint in hex notation * @return string UTF-8 literal string */ @@ -310,7 +310,7 @@ protected function codepointToUtf8($codepoint) public function testJavascriptEscapingEscapesOwaspRecommendedRanges() { $immune = array(',', '.', '_'); // Exceptions to escaping ranges - for ($chr=0; $chr < 0xFF; $chr++) { + for ($chr=0; $chr < 0xFF; $chr++) { if ($chr >= 0x30 && $chr <= 0x39 || $chr >= 0x41 && $chr <= 0x5A || $chr >= 0x61 && $chr <= 0x7A) { @@ -333,7 +333,7 @@ public function testJavascriptEscapingEscapesOwaspRecommendedRanges() public function testHtmlAttributeEscapingEscapesOwaspRecommendedRanges() { $immune = array(',', '.', '-', '_'); // Exceptions to escaping ranges - for ($chr=0; $chr < 0xFF; $chr++) { + for ($chr=0; $chr < 0xFF; $chr++) { if ($chr >= 0x30 && $chr <= 0x39 || $chr >= 0x41 && $chr <= 0x5A || $chr >= 0x61 && $chr <= 0x7A) { @@ -356,7 +356,7 @@ public function testHtmlAttributeEscapingEscapesOwaspRecommendedRanges() public function testCssEscapingEscapesOwaspRecommendedRanges() { $immune = array(); // CSS has no exceptions to escaping ranges - for ($chr=0; $chr < 0xFF; $chr++) { + for ($chr=0; $chr < 0xFF; $chr++) { if ($chr >= 0x30 && $chr <= 0x39 || $chr >= 0x41 && $chr <= 0x5A || $chr >= 0x61 && $chr <= 0x7A) { From cbadbc343bfe2f3972631c78e4093024def4ad60 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Wed, 11 Jul 2012 21:47:49 +0200 Subject: [PATCH 2/4] uppdate case hex escapings --- src/Escaper.php | 32 ++++++++++++++++---------------- test/EscaperTest.php | 28 ++++++++++++++-------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/Escaper.php b/src/Escaper.php index 7d36ea4..a032cf6 100644 --- a/src/Escaper.php +++ b/src/Escaper.php @@ -257,7 +257,7 @@ public function htmlAttrMatcher($matches) if (($ord <= 0x1f && $chr != "\t" && $chr != "\n" && $chr != "\r") || ($ord >= 0x7f && $ord <= 0x9f) ) { - return '�'; + return '�'; } /** @@ -269,19 +269,20 @@ public function htmlAttrMatcher($matches) } $hex = bin2hex($chr); - $int = hexdec($hex); - if (isset(static::$htmlNamedEntityMap[$int])) { - return '&' . static::$htmlNamedEntityMap[$int] . ';'; + $ord = hexdec($hex); + if (isset(static::$htmlNamedEntityMap[$ord])) { + return '&' . static::$htmlNamedEntityMap[$ord] . ';'; } /** - * Per OWASP recommendations, we'll use hex entities for any other - * characters where a named entity does not exist. + * Per OWASP recommendations, we'll use upper hex entities + * for any other characters where a named entity does not exist. */ - if ($int > 255) { - $hex = str_pad($hex, 4, '0', \STR_PAD_LEFT); + if ($ord > 255) { + return sprintf('&#x%04X;', $ord); + } else { + return sprintf('&#x%02X;', $ord); } - return '&#x' . $hex . ';'; } /** @@ -295,10 +296,10 @@ public function jsMatcher($matches) { $chr = $matches[0]; if (strlen($chr) == 1) { - return '\\x' . bin2hex($chr); + return sprintf('\\x%02X', ord($chr)); } else { $chr = $this->convertEncoding($chr, 'UTF-16BE', 'UTF-8'); - return '\\u' . str_pad(bin2hex($chr), 4, '0', \STR_PAD_LEFT); + return sprintf('\\u%04s', strtoupper(bin2hex($chr))); } } @@ -312,14 +313,13 @@ public function jsMatcher($matches) public function cssMatcher($matches) { $chr = $matches[0]; - if ($chr === "\0") { - return '\\0 '; - } elseif (strlen($chr) == 1) { - return '\\' . ltrim(bin2hex($chr), '0') . ' '; + if (strlen($chr) == 1) { + $ord = ord($chr); } else { $chr = $this->convertEncoding($chr, 'UTF-16BE', 'UTF-8'); - return '\\' . ltrim(bin2hex($chr), '0') . ' '; + $ord = hexdec(bin2hex($chr)); } + return sprintf('\\%X ', $ord); } /** diff --git a/test/EscaperTest.php b/test/EscaperTest.php index f1e0ab2..e134ae2 100644 --- a/test/EscaperTest.php +++ b/test/EscaperTest.php @@ -59,10 +59,10 @@ class EscaperTest extends \PHPUnit_Framework_TestCase '0' => '0', '9' => '9', /* Basic control characters and null */ - "\r" => ' ', - "\n" => ' ', + "\r" => ' ', + "\n" => ' ', "\t" => ' ', - "\0" => '�', // should use Unicode replacement char + "\0" => '�', // should use Unicode replacement char /* Encode chars as named entities where possible */ '<' => '<', '>' => '>', @@ -74,8 +74,8 @@ class EscaperTest extends \PHPUnit_Framework_TestCase protected $jsSpecialChars = array( /* HTML special chars - escape without exception to hex */ - '<' => '\\x3c', - '>' => '\\x3e', + '<' => '\\x3C', + '>' => '\\x3E', '\'' => '\\x27', '"' => '\\x22', '&' => '\\x26', @@ -93,8 +93,8 @@ class EscaperTest extends \PHPUnit_Framework_TestCase '0' => '0', '9' => '9', /* Basic control characters and null */ - "\r" => '\\x0d', - "\n" => '\\x0a', + "\r" => '\\x0D', + "\n" => '\\x0A', "\t" => '\\x09', "\0" => '\\x00', /* Encode spaces for quoteless attribute protection */ @@ -138,17 +138,17 @@ class EscaperTest extends \PHPUnit_Framework_TestCase protected $cssSpecialChars = array( /* HTML special chars - escape without exception to hex */ - '<' => '\\3c ', - '>' => '\\3e ', + '<' => '\\3C ', + '>' => '\\3E ', '\'' => '\\27 ', '"' => '\\22 ', '&' => '\\26 ', /* Characters beyond ASCII value 255 to unicode escape */ 'Ā' => '\\100 ', /* Immune chars excluded */ - ',' => '\\2c ', - '.' => '\\2e ', - '_' => '\\5f ', + ',' => '\\2C ', + '.' => '\\2E ', + '_' => '\\5F ', /* Basic alnums exluded */ 'a' => 'a', 'A' => 'A', @@ -157,8 +157,8 @@ class EscaperTest extends \PHPUnit_Framework_TestCase '0' => '0', '9' => '9', /* Basic control characters and null */ - "\r" => '\\d ', - "\n" => '\\a ', + "\r" => '\\D ', + "\n" => '\\A ', "\t" => '\\9 ', "\0" => '\\0 ', /* Encode spaces for quoteless attribute protection */ From af821d0f6b3f76767293ba1288b51c57343715f3 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Wed, 11 Jul 2012 21:49:19 +0200 Subject: [PATCH 3/4] protected internal *Matcher callback methods --- src/Escaper.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Escaper.php b/src/Escaper.php index a032cf6..bd29059 100644 --- a/src/Escaper.php +++ b/src/Escaper.php @@ -245,7 +245,7 @@ public function escapeCss($string) * @param array $matches * @return string */ - public function htmlAttrMatcher($matches) + protected function htmlAttrMatcher($matches) { $chr = $matches[0]; $ord = ord($chr); @@ -292,7 +292,7 @@ public function htmlAttrMatcher($matches) * @param array $matches * @return string */ - public function jsMatcher($matches) + protected function jsMatcher($matches) { $chr = $matches[0]; if (strlen($chr) == 1) { @@ -310,7 +310,7 @@ public function jsMatcher($matches) * @param array $matches * @return string */ - public function cssMatcher($matches) + protected function cssMatcher($matches) { $chr = $matches[0]; if (strlen($chr) == 1) { From 13a8c461b7b7b0e571a1e48da88d3bda167d0626 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Wed, 11 Jul 2012 21:56:57 +0200 Subject: [PATCH 4/4] use 'defined('ENT_SUBSTITUTE')' instead of version compare against PHP version --- src/Escaper.php | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/Escaper.php b/src/Escaper.php index bd29059..399e4fd 100644 --- a/src/Escaper.php +++ b/src/Escaper.php @@ -57,33 +57,21 @@ class Escaper /** * Static Matcher which escapes characters for HTML Attribute contexts * -<<<<<<< HEAD - * @var Closure -======= * @var callable ->>>>>>> Zend\Escaper (micro) optimisations */ protected $htmlAttrMatcher; /** * Static Matcher which escapes characters for Javascript contexts * -<<<<<<< HEAD - * @var Closure -======= * @var callable ->>>>>>> Zend\Escaper (micro) optimisations */ protected $jsMatcher; /** * Static Matcher which escapes characters for CSS Attribute contexts * -<<<<<<< HEAD - * @var Closure -======= * @var callable ->>>>>>> Zend\Escaper (micro) optimisations */ protected $cssMatcher; @@ -132,8 +120,8 @@ public function __construct($encoding = null) $this->encoding = $encoding; } - if (version_compare(\PHP_VERSION, '5.4') >= 0) { - $this->htmlSpecialCharsFlags = \ENT_QUOTES | \ENT_SUBSTITUTE; + if (defined('ENT_SUBSTITUTE')) { + $this->htmlSpecialCharsFlags|= \ENT_SUBSTITUTE; } // set matcher callbacks