Skip to content

Commit

Permalink
fix(output): fewer view $vars will be output by accident
Browse files Browse the repository at this point in the history
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 Elgg#8218
  • Loading branch information
mrclay committed Jun 4, 2015
1 parent b5909fc commit 73364c1
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 0 deletions.
7 changes: 7 additions & 0 deletions engine/lib/output.php
Original file line number Diff line number Diff line change
Expand Up @@ -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>)
Expand All @@ -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) {
Expand Down
39 changes: 39 additions & 0 deletions engine/tests/phpunit/Elgg/lib/output/FormatAttributesTest.php
Original file line number Diff line number Diff line change
@@ -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 73364c1

Please sign in to comment.