diff --git a/core/lib/Drupal/Core/Template/Attribute.php b/core/lib/Drupal/Core/Template/Attribute.php index e9dee43..ecd1e05 100644 --- a/core/lib/Drupal/Core/Template/Attribute.php +++ b/core/lib/Drupal/Core/Template/Attribute.php @@ -123,12 +123,13 @@ protected function createAttributeValue($name, $value) { $value = new AttributeBoolean($name, $value); } // As a development aid, we allow the value to be a safe string object. - elseif (!is_object($value) || $value instanceof SafeStringInterface) { + elseif (SafeMarkup::isSafe($value)) { // Attributes are not supposed to display HTML markup, so we just convert // the value to plain text. - if (SafeMarkup::isSafe($value)) { - $value = PlainTextOutput::renderFromHtml($value); - } + $value = PlainTextOutput::renderFromHtml($value); + $value = new AttributeString($name, $value); + } + elseif (!is_object($value)) { $value = new AttributeString($name, $value); } return $value; diff --git a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php index a2a4e25..3b0c5c1 100644 --- a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php +++ b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php @@ -12,7 +12,6 @@ use Drupal\Core\Access\AccessResult; use Drupal\Core\Cache\Context\CacheContextsManager; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; -use Drupal\Core\Entity\EntityChangedInterface; use Drupal\Core\Form\EnforcedResponseException; use Drupal\Core\Form\FormBuilder; use Drupal\Core\Form\FormBuilderInterface; diff --git a/core/tests/Drupal/Tests/Core/Template/AttributeTest.php b/core/tests/Drupal/Tests/Core/Template/AttributeTest.php index b4a192d..6766525 100644 --- a/core/tests/Drupal/Tests/Core/Template/AttributeTest.php +++ b/core/tests/Drupal/Tests/Core/Template/AttributeTest.php @@ -7,6 +7,8 @@ namespace Drupal\Tests\Core\Template; +use Drupal\Component\Utility\Html; +use Drupal\Core\Render\SafeString; use Drupal\Core\Template\Attribute; use Drupal\Core\Template\AttributeArray; use Drupal\Core\Template\AttributeString; @@ -341,6 +343,27 @@ public function testPrint() { } /** + * @covers ::createAttributeValue + * @dataProvider providerTestAttributeValues + */ + public function testAttributeValues(array $attributes, $expected) { + $this->assertEquals($expected, (new Attribute($attributes))->__toString()); + } + + public function providerTestAttributeValues() { + $data = []; + + $string = '"> "'; + $data['safe-object-xss1'] = [['title' => SafeString::create($string)], ' title=""> alert(123)""']; + $data['non-safe-object-xss1'] = [['title' => $string], ' title="' . Html::escape($string) . '"']; + $string = '">'; + $data['safe-object-xss2'] = [['title' => SafeString::create($string)], ' title="">alert(123)"']; + $data['non-safe-object-xss2'] = [['title' => $string], ' title="' . Html::escape($string) . '"']; + + return $data; + } + + /** * Checks that the given CSS class is present in the given HTML snippet. * * @param string $class