diff --git a/core/includes/common.inc b/core/includes/common.inc index 7a97da31902283e4d52368a4d3fc5c98bf924de7..1cf53b647a5e86c3f9a3c17d949280a4678c65b2 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -1371,12 +1371,15 @@ function filter_xss($string, $allowed_tags = array('a', 'em', 'strong', 'cite', * @see filter_xss() */ function partial_decode_entities_safe($string) { - // Decimal numeric entities. - $string = preg_replace('/&#([0-9]+;)/', '&#\1', $string); - // Hexadecimal numeric entities. - $string = preg_replace('/&#[Xx]0*((?:[0-9A-Fa-f]{2})+;)/', '&#x\1', $string); - // Named entities. - $string = preg_replace('/&([A-Za-z][A-Za-z0-9]*;)/', '&\1', $string); + // Do nothing if there are no '&' characters in $string. + if(strpos($string, '&') !== FALSE) { + // Decimal numeric entities. + $string = preg_replace('/&#([0-9]+;)/', '&#\1', $string); + // Hexadecimal numeric entities. + $string = preg_replace('/&#[Xx]0*((?:[0-9A-Fa-f]{2})+;)/', '&#x\1', $string); + // Named entities. + $string = preg_replace('/&([A-Za-z][A-Za-z0-9]*;)/', '&\1', $string); + } return $string; } diff --git a/core/lib/Drupal/Core/Template/AttributeString.php b/core/lib/Drupal/Core/Template/AttributeString.php index 9c953bd450ee06a9fa51f1eef90c631ba82fcf0d..87ab6bd7c13e550324c045915d294e5df1e6082a 100644 --- a/core/lib/Drupal/Core/Template/AttributeString.php +++ b/core/lib/Drupal/Core/Template/AttributeString.php @@ -31,11 +31,9 @@ public function __toString() { $this->printed = TRUE; $string = check_plain($this->value); - // Decode legal HTML entities on our security whitelist that may have been - // inappropriately sanitized by check_plain(). - if(strpos($string, '&') !== FALSE) { - $string = partial_decode_entities_safe($string); - } + // Allow well-formed HTML entities on our security whitelist. + $string = partial_decode_entities_safe($string); + return $string; } diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/AttributesUnitTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/AttributesUnitTest.php index 77a0e6b5700e397be2f6fd2f3ccc8c8a91cfdab4..0e51b1ebf931529afe7e4ee8c256d44b0ad088b2 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Common/AttributesUnitTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Common/AttributesUnitTest.php @@ -47,6 +47,9 @@ function testDrupalAttributes() { // Verify that HTML encoded named characters are preserved. $this->assertIdentical((string) new Attribute(array('title' => '®')), ' title="®"', 'HTML Encoded named character entity attribute values are preserved.'); + // Verify that iconic Unicode characters are preserved. + $this->assertIdentical((string) new Attribute(array('title' => '©')), ' title="©"', 'Iconic Unicode character attribute values are preserved.'); + // Verify multi-value attributes are concatenated with spaces. $attributes = array('class' => array('first', 'last')); $this->assertIdentical((string) new Attribute(array('class' => array('first', 'last'))), ' class="first last"', 'Concatenate multi-value attributes.');