commit 3aff1f8e233f93f7c40551d320f9de785396d2c6 Author: Joel Pittet Date: Sun Jul 12 14:34:52 2015 -0700 updates diff --git a/core/lib/Drupal/Core/Template/AttributeString.php b/core/lib/Drupal/Core/Template/AttributeString.php index f6693b0..2a71473 100644 --- a/core/lib/Drupal/Core/Template/AttributeString.php +++ b/core/lib/Drupal/Core/Template/AttributeString.php @@ -31,7 +31,8 @@ class AttributeString extends AttributeValueBase { */ public function __toString() { if (SafeMarkup::isSafe($this->value)) { - return $this->value; + // Only replace double quotes so we don't break the attribute. + return str_replace('"', '"', $this->value); } else { return htmlspecialchars($this->value, ENT_QUOTES, 'UTF-8'); diff --git a/core/tests/Drupal/Tests/Core/Template/AttributeTest.php b/core/tests/Drupal/Tests/Core/Template/AttributeTest.php index b4a192d..b6f29f4 100644 --- a/core/tests/Drupal/Tests/Core/Template/AttributeTest.php +++ b/core/tests/Drupal/Tests/Core/Template/AttributeTest.php @@ -7,9 +7,11 @@ namespace Drupal\Tests\Core\Template; +use Drupal\Component\Utility\SafeMarkup; use Drupal\Core\Template\Attribute; use Drupal\Core\Template\AttributeArray; use Drupal\Core\Template\AttributeString; +use Drupal\Core\Template\TwigExtension; use Drupal\Tests\UnitTestCase; /** @@ -420,4 +422,60 @@ public function testStorage() { $this->assertEquals(array('class' => new AttributeArray('class', array('example-class'))), $attribute->storage()); } + /** + * Test attribute escaping. + */ + public function testAttributeEscaping() { + $attributes = new Attribute(['title' => 'tag&\'"']); + + // Entire attribute escaping. + $result = (string) $attributes; + $this->assertEquals(' title="<span>tag</span>&'""', $result); + + // Attribute value escaping. + $result = (string) $attributes['title']; + $this->assertEquals('<span>tag</span>&'"', $result); + + $attributes = new Attribute(['title' => SafeMarkup::set('tag&\'"')]); + // Entire attribute escaping with safe values. + $result = (string) $attributes; + $this->assertEquals(' title="tag&\'"""', $result); + + // Attribute value escaping with safe values. + $result = (string) $attributes['title']; + $this->assertEquals('tag&\'"', $result); + } + + /** + * Tests the twig escaping Attribute. + */ + public function testTwigAttributeEscaping() { + $loader = new \Twig_Loader_String(); + $twig = new \Twig_Environment($loader); + $renderer = $this->getMock('\Drupal\Core\Render\RendererInterface'); + $twig->addExtension(new TwigExtension($renderer)); + + $attributes = new Attribute(['title' => 'tag&\'"']); + $context = ['attributes' => $attributes]; + + // Entire attribute escaping. + $result = $twig->render('{{ attributes }}', $context); + $this->assertEquals(' title="<span>tag</span>&'""', $result); + + // Attribute value escaping. + $result = $twig->render('{{ attributes.title }}', $context); + $this->assertEquals('<span>tag</span>&'"', $result); + + $attributes = new Attribute(['title' => SafeMarkup::set('tag&\'"')]); + $context = ['attributes' => $attributes]; + + // Entire attribute escaping with safe values. + $result = $twig->render('{{ attributes }}', $context); + $this->assertEquals(' title="tag&\'""', $result); + + // Attribute value escaping with safe values. + $result = $twig->render('{{ attributes.title }}', $context); + $this->assertEquals('tag&\'"', $result); + } + }