Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Better HTML decoding and output/email encoding #430

Closed
wants to merge 1 commit into from

1 participant

Steve Clay
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 7, 2012
  1. Steve Clay
This page is out of date. Refresh to see the latest.
4 actions/profile/edit.php
View
@@ -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
42 engine/lib/output.php
View
@@ -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;
+}
12 engine/lib/upgrades/2010052601.php
View
@@ -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;
}
2  mod/blog/views/default/forms/blog/save.php
View
@@ -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');
8 mod/groups/actions/groups/edit.php
View
@@ -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') {
4 views/default/output/email.php
View
@@ -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.