summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Andreev <narf@devilix.net>2016-09-27 13:59:37 +0200
committerAndrey Andreev <narf@devilix.net>2016-09-27 13:59:37 +0200
commiteea02de557834006c5d6a0bfccca7f39e75bf3a8 (patch)
treeae9800d9d0f358b9df53d559f9eaa95b7b3df218
parent8a15f5af819424087b6676709d98de6fa5fc6115 (diff)
Fix entity_decode() issue
-rw-r--r--system/core/Security.php39
-rw-r--r--tests/codeigniter/core/Security_test.php6
-rw-r--r--user_guide_src/source/changelog.rst4
3 files changed, 32 insertions, 17 deletions
diff --git a/system/core/Security.php b/system/core/Security.php
index 3a5da4fde..4a69daa18 100644
--- a/system/core/Security.php
+++ b/system/core/Security.php
@@ -669,6 +669,22 @@ class CI_Security {
? ENT_COMPAT | ENT_HTML5
: ENT_COMPAT;
+ if ( ! isset($_entities))
+ {
+ $_entities = array_map('strtolower', get_html_translation_table(HTML_ENTITIES, $flag, $charset));
+
+ // If we're not on PHP 5.4+, add the possibly dangerous HTML 5
+ // entities to the array manually
+ if ($flag === ENT_COMPAT)
+ {
+ $_entities[':'] = '&colon;';
+ $_entities['('] = '&lpar;';
+ $_entities[')'] = '&rpar;';
+ $_entities["\n"] = '&NewLine;';
+ $_entities["\t"] = '&Tab;';
+ }
+ }
+
do
{
$str_compare = $str;
@@ -676,22 +692,6 @@ class CI_Security {
// Decode standard entities, avoiding false positives
if (preg_match_all('/&[a-z]{2,}(?![a-z;])/i', $str, $matches))
{
- if ( ! isset($_entities))
- {
- $_entities = array_map('strtolower', get_html_translation_table(HTML_ENTITIES, $flag, $charset));
-
- // If we're not on PHP 5.4+, add the possibly dangerous HTML 5
- // entities to the array manually
- if ($flag === ENT_COMPAT)
- {
- $_entities[':'] = '&colon;';
- $_entities['('] = '&lpar;';
- $_entities[')'] = '&rpar;';
- $_entities["\n"] = '&newline;';
- $_entities["\t"] = '&tab;';
- }
- }
-
$replace = array();
$matches = array_unique(array_map('strtolower', $matches[0]));
foreach ($matches as &$match)
@@ -702,7 +702,7 @@ class CI_Security {
}
}
- $str = str_ireplace(array_keys($replace), array_values($replace), $str);
+ $str = str_replace(array_keys($replace), array_values($replace), $str);
}
// Decode numeric & UTF16 two byte entities
@@ -711,6 +711,11 @@ class CI_Security {
$flag,
$charset
);
+
+ if ($flag === ENT_COMPAT)
+ {
+ $str = str_replace(array_values($_entities), array_keys($_entities), $str);
+ }
}
while ($str_compare !== $str);
return $str;
diff --git a/tests/codeigniter/core/Security_test.php b/tests/codeigniter/core/Security_test.php
index 8328c37cb..cbf0285ec 100644
--- a/tests/codeigniter/core/Security_test.php
+++ b/tests/codeigniter/core/Security_test.php
@@ -270,6 +270,12 @@ class Security_test extends CI_TestCase {
$this->assertEquals('<div>Hello <b>Booya</b></div>', $decoded);
+ $this->assertEquals('colon:', $this->security->entity_decode('colon&colon;'));
+ $this->assertEquals("NewLine\n", $this->security->entity_decode('NewLine&NewLine;'));
+ $this->assertEquals("Tab\t", $this->security->entity_decode('Tab&Tab;'));
+ $this->assertEquals("lpar(", $this->security->entity_decode('lpar&lpar;'));
+ $this->assertEquals("rpar)", $this->security->entity_decode('rpar&rpar;'));
+
// Issue #3057 (https://github.com/bcit-ci/CodeIgniter/issues/3057)
$this->assertEquals(
'&foo should not include a semicolon',
diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst
index d41e79945..a0ed34a2f 100644
--- a/user_guide_src/source/changelog.rst
+++ b/user_guide_src/source/changelog.rst
@@ -7,6 +7,10 @@ Version 3.1.1
Release Date: Not Released
+- **Security**
+
+ - Fixed a flaw in :doc:`Security Library <libraries/security>` method ``entity_decode()`` (used by ``xss_clean()``) that affects HTML 5 entities when using PHP 5.3.
+
- General Changes
- Added ``E_PARSE`` to the list of error levels detected by the shutdown handler.