Permalink
Browse files

fix(output): fewer view $vars will be output by accident

A general problem is views passing along arbitrary $vars values to views
like output/url, which treat unrecognized $vars as HTML attributes. This
at least strips keys with underscores, which are definitely not meant
to be HTML attributes.

Fixes #8218
  • Loading branch information...
mrclay committed Apr 27, 2015
1 parent b5909fc commit 4560d389619d8eb950abcc504268cf92edae167c
@@ -85,6 +85,12 @@ This should work in Elgg 2.0:
});
</script>
+Attribute formatter removes keys with underscores
+-------------------------------------------------
+
+``elgg_format_attributes()`` (and all APIs that use it) now filter out attributes whose name contains an
+underscore. If the attribute begins with ``data-``, however, it will not be removed.
+
Breadcrumbs
-----------
View
@@ -132,6 +132,8 @@ function elgg_format_bytes($size, $precision = 2) {
*
* @note usually for HTML, but could be useful for XML too...
*
+ * @note Key names containing "_" will be ignored unless they start with "data-"
+ *
* @param array $attrs An associative array of attr => val pairs
*
* @return string HTML attributes to be inserted into a tag (e.g., <tag $attrs>)
@@ -154,6 +156,11 @@ function elgg_format_attributes(array $attrs = array()) {
}
foreach ($attrs as $attr => $val) {
+ if (0 !== strpos($attr, 'data-') && false !== strpos($attr, '_')) {
+ // this is probably a view $vars variable not meant for output
+ continue;
+ }
+
$attr = strtolower($attr);
if ($val === true) {
@@ -0,0 +1,39 @@
+<?php
+namespace Elgg\lib\output;
+
+class FormatAttributesTest extends \PHPUnit_Framework_TestCase {
+
+ public function testGeneralUsage() {
+ $attrs = [
+ 'A' => 'Hello & &amp; < &lt;',
+ 'b' => false, // ignored
+ 'c' => true,
+ 'd' => null, // ignored
+ 'e' => ['&', '&amp;', '<', '&lt;'],
+ 'f' => (object)['foo' => 'bar'], // ignored
+ ];
+ $expected = 'a="Hello &amp; &amp; &lt; &lt;" c="c" e="&amp; &amp; &lt; &lt;"';
+
+ $this->assertEquals($expected, elgg_format_attributes($attrs));
+ }
+
+ public function testFiltersUnderscoreKeysExceptDataAttributes() {
+ $attrs = [
+ 'foo_bar' => 'a',
+ 'data-foo_bar' => 'b',
+ ];
+ $expected = 'data-foo_bar="b"';
+
+ $this->assertEquals($expected, elgg_format_attributes($attrs));
+ }
+
+ public function testLowercasesAllAttributes() {
+ $attrs = [
+ 'A-B' => true,
+ 'C-D' => 'C-D',
+ ];
+ $expected = 'a-b="a-b" c-d="C-D"';
+
+ $this->assertEquals($expected, elgg_format_attributes($attrs));
+ }
+}

0 comments on commit 4560d38

Please sign in to comment.