diff --git a/includes/common.inc b/includes/common.inc index ceac115..0d26a0b 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -1610,6 +1610,7 @@ function _filter_xss_attributes($attr) { $thisval = filter_xss_bad_protocol($match[1]); if (!$skip) { + _filter_xss_ie_fix_attr_value($thisval); $attrarr[] = "$attrname=\"$thisval\""; } $working = 1; @@ -1622,6 +1623,7 @@ function _filter_xss_attributes($attr) { $thisval = filter_xss_bad_protocol($match[1]); if (!$skip) { + _filter_xss_ie_fix_attr_value($thisval); $attrarr[] = "$attrname='$thisval'"; } $working = 1; $mode = 0; @@ -1633,6 +1635,7 @@ function _filter_xss_attributes($attr) { $thisval = filter_xss_bad_protocol($match[1]); if (!$skip) { + _filter_xss_ie_fix_attr_value($thisval); $attrarr[] = "$attrname=\"$thisval\""; } $working = 1; $mode = 0; @@ -1666,6 +1669,22 @@ function _filter_xss_attributes($attr) { } /** + * Fix for IE < 9 broken handling of ` character. + * + * @param $string + * Attribute value to be modified by reference. + */ +function _filter_xss_ie_fix_attr_value(&$string) { + if (strpos($string, '`') !== FALSE) { + // IE < 9 quoting would already be triggered by the presence of any "' <> + if (!preg_match('/["\' <>]/', $string)) { + // Trailing space triggers IE < 9 to correctly quote the value. + $string .= ' '; + } + } +} + +/** * Processes an HTML attribute value and strips dangerous protocols from URLs. * * @param $string @@ -2419,7 +2438,7 @@ function drupal_http_header_attributes(array $attributes = array()) { function drupal_attributes(array $attributes = array()) { foreach ($attributes as $attribute => &$data) { $data = implode(' ', (array) $data); - $data = $attribute . '="' . check_plain($data) . '"'; + $data = $attribute . '="' . _filter_xss_ie_fix_attr_value(check_plain($data)) . '"'; } return $attributes ? ' ' . implode(' ', $attributes) : ''; } diff --git a/modules/filter/filter.test b/modules/filter/filter.test index ddea6af..0f42636 100644 --- a/modules/filter/filter.test +++ b/modules/filter/filter.test @@ -1128,6 +1128,11 @@ class FilterUnitTestCase extends DrupalUnitTestCase { $f = filter_xss("Who&amp;#039; Online"); $this->assertNormalized($f, "who&#039; online", 'HTML filter -- double encoded html entity number'); + + // Check a space is appended to the attribute whenever the attribute value + // contains the accent character. @see _filter_xss_ie_fix_attr_value() + $text = filter_xss('', array('input')); + $this->assertEqual($text, ''); } /** diff --git a/modules/simpletest/tests/common.test b/modules/simpletest/tests/common.test index bf85576..c836104 100644 --- a/modules/simpletest/tests/common.test +++ b/modules/simpletest/tests/common.test @@ -2772,6 +2772,7 @@ class DrupalAttributesUnitTest extends DrupalUnitTestCase { // Verify empty attribute values are rendered. $this->assertIdentical(drupal_attributes(array('alt' => '')), ' alt=""', 'Empty attribute value #1.'); $this->assertIdentical(drupal_attributes(array('alt' => NULL)), ' alt=""', 'Empty attribute value #2.'); + $this->assertIdentical(drupal_attributes(array('alt' => '``onmouseover=alert(1)')), ' alt="``onmouseover=alert(1) "'); // Verify multiple attributes are rendered. $attributes = array(