Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Better HTML decoding and output/email encoding #430

Closed
wants to merge 1 commit into from

1 participant

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 7, 2012
  1. @mrclay
This page is out of date. Refresh to see the latest.
View
4 actions/profile/edit.php
@@ -25,7 +25,7 @@
* wrapper for recursive array walk decoding
*/
function profile_array_decoder(&$v) {
- $v = html_entity_decode($v, ENT_COMPAT, 'UTF-8');
+ $v = _elgg_html_decode($v);
}
$profile_fields = elgg_get_config('profile_fields');
@@ -37,7 +37,7 @@ function profile_array_decoder(&$v) {
if (is_array($value)) {
array_walk_recursive($value, 'profile_array_decoder');
} else {
- $value = html_entity_decode($value, ENT_COMPAT, 'UTF-8');
+ $value = _elgg_html_decode($value);
}
// limit to reasonable sizes
View
42 engine/lib/output.php
@@ -398,3 +398,45 @@ function elgg_strip_tags($string) {
return $string;
}
+
+/**
+ * Apply html_entity_decode() to a string while re-entitising HTML
+ * special char entities to prevent them from being decoded back to their
+ * unsafe original forms.
+ *
+ * This relies on html_entity_decode() not translating entities when
+ * doing so leaves behind another entity, e.g. > if decoded would
+ * create > which is another entity itself. This seems to escape the
+ * usual behaviour where any two paired entities creating a HTML tag are
+ * usually decoded, i.e. a lone > is not decoded, but <foo> would
+ * be decoded to <foo> since it creates a full tag.
+ *
+ * Note: This function is poorly explained in the manual - which is really
+ * bad given its potential for misuse on user input already escaped elsewhere.
+ * Stackoverflow is littered with advice to use this function in the precise
+ * way that would lead to user input being capable of injecting arbitrary HTML.
+ *
+ * @param string $string
+ *
+ * @return string
+ *
+ * @author Pádraic Brady
+ * @copyright Copyright (c) 2010 Pádraic Brady (http://blog.astrumfutura.com)
+ * @license Released under dual-license GPL2/MIT by explicit permission of Pádraic Brady
+ *
+ * @access private
+ */
+function _elgg_html_decode($string) {
+ $string = str_replace(
+ array('&gt;', '&lt;', '&amp;', '&quot;', '&#039;'),
+ array('&amp;gt;', '&amp;lt;', '&amp;amp;', '&amp;quot;', '&amp;#039;'),
+ $string
+ );
+ $string = html_entity_decode($string, ENT_NOQUOTES, 'UTF-8');
+ $string = str_replace(
+ array('&amp;gt;', '&amp;lt;', '&amp;amp;', '&amp;quot;', '&amp;#039;'),
+ array('&gt;', '&lt;', '&amp;', '&quot;', '&#039;'),
+ $string
+ );
+ return $string;
+}
View
12 engine/lib/upgrades/2010052601.php
@@ -9,14 +9,14 @@
$groups = elgg_get_entities($params);
if ($groups) {
foreach ($groups as $group) {
- $group->name = html_entity_decode($group->name, ENT_COMPAT, 'UTF-8');
- $group->description = html_entity_decode($group->description, ENT_COMPAT, 'UTF-8');
- $group->briefdescription = html_entity_decode($group->briefdescription, ENT_COMPAT, 'UTF-8');
- $group->website = html_entity_decode($group->website, ENT_COMPAT, 'UTF-8');
+ $group->name = _elgg_html_decode($group->name);
+ $group->description = _elgg_html_decode($group->description);
+ $group->briefdescription = _elgg_html_decode($group->briefdescription);
+ $group->website = _elgg_html_decode($group->website);
if ($group->interests) {
$tags = $group->interests;
- foreach ($tags as $index=>$tag) {
- $tags[$index] = html_entity_decode($tag, ENT_COMPAT, 'UTF-8');
+ foreach ($tags as $index => $tag) {
+ $tags[$index] = _elgg_html_decode($tag);
}
$group->interests = $tags;
}
View
2  mod/blog/views/default/forms/blog/save.php
@@ -53,7 +53,7 @@
$excerpt_input = elgg_view('input/text', array(
'name' => 'excerpt',
'id' => 'blog_excerpt',
- 'value' => html_entity_decode($vars['excerpt'], ENT_COMPAT, 'UTF-8')
+ 'value' => _elgg_html_decode($vars['excerpt'])
));
$body_label = elgg_echo('blog:body');
View
8 mod/groups/actions/groups/edit.php
@@ -8,15 +8,15 @@
// Load configuration
global $CONFIG;
+elgg_make_sticky_form('groups');
+
/**
* wrapper for recursive array walk decoding
*/
function profile_array_decoder(&$v) {
- $v = html_entity_decode($v, ENT_COMPAT, 'UTF-8');
+ $v = _elgg_html_decode($v);
}
-elgg_make_sticky_form('groups');
-
// Get group fields
$input = array();
foreach ($CONFIG->group as $shortname => $valuetype) {
@@ -25,7 +25,7 @@ function profile_array_decoder(&$v) {
if (is_array($input[$shortname])) {
array_walk_recursive($input[$shortname], 'profile_array_decoder');
} else {
- $input[$shortname] = html_entity_decode($input[$shortname], ENT_COMPAT, 'UTF-8');
+ $input[$shortname] = _elgg_html_decode($input[$shortname]);
}
if ($valuetype == 'tags') {
View
4 views/default/output/email.php
@@ -10,6 +10,8 @@
*
*/
+$encoded_value = htmlspecialchars($vars['value'], ENT_QUOTES, 'UTF-8');
+
if (!empty($vars['value'])) {
- echo "<a href=\"mailto:" . $vars['value'] . "\">". htmlspecialchars($vars['value'], ENT_QUOTES, 'UTF-8', false) ."</a>";
+ echo "<a href=\"mailto:$encoded_value\">$encoded_value</a>";
}
Something went wrong with that request. Please try again.