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&#039; Online");
$this->assertNormalized($f, "who' 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(