diff --git a/core/includes/theme.inc b/core/includes/theme.inc index 1bd3e98..0e25e63 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -372,9 +372,12 @@ function theme_get_setting($setting_name, $theme = NULL) { * @return string * The rendered string. * + * @throws \Exception + * Thrown when an object is passed in which cannot be printed. + * * @see \Drupal\Core\Template\TwigExtension::escapeFilter() */ -function theme_autoescape($arg) { +function theme_escape_and_render($arg) { if ($arg instanceOf SafeStringInterface) { return (string) $arg; } diff --git a/core/modules/language/language.admin.inc b/core/modules/language/language.admin.inc index 3f860de..b80207c 100644 --- a/core/modules/language/language.admin.inc +++ b/core/modules/language/language.admin.inc @@ -201,5 +201,5 @@ function template_preprocess_language_content_settings_table(&$variables) { * @ingroup themeable */ function theme_language_content_settings_table($variables) { - return '

' . $variables['build']['#title'] . '

' . drupal_render($variables['build']); + return '

' . theme_escape_and_render($variables['build']['#title']) . '

' . drupal_render($variables['build']); } diff --git a/core/tests/Drupal/KernelTests/Core/Theme/ThemeAutoescapeTest.php b/core/tests/Drupal/KernelTests/Core/Theme/ThemeAutoescapeTest.php index 8b76b0d..f015e57 100644 --- a/core/tests/Drupal/KernelTests/Core/Theme/ThemeAutoescapeTest.php +++ b/core/tests/Drupal/KernelTests/Core/Theme/ThemeAutoescapeTest.php @@ -8,8 +8,10 @@ namespace Drupal\KernelTests\Core\Theme; use Drupal\Component\Utility\Html; +use Drupal\Core\Link; use Drupal\Core\Render\RenderContext; use Drupal\Core\Render\SafeString; +use Drupal\Core\Url; use Drupal\KernelTests\KernelTestBase; /** @@ -20,33 +22,65 @@ class ThemeAutoescapeTest extends KernelTestBase { /** + * {@inheritdoc} + */ + public static $modules = ['system']; + + /** + * {@inheritdoc} + */ + protected function setUp() { + parent::setUp(); + + $this->installSchema('system', 'router'); + \Drupal::service('router.builder')->rebuild(); + } + + /** * Tests automatic escaping. * - * @dataProvider providerTestThemeAutoescape + * @dataProvider providerTestThemeEscapeAndRender */ - public function testThemeAutoescape($arg, $expected) { + public function testThemeEscapeAndRender($arg, $expected) { + if (is_array($arg) && isset($arg['#type']) && $arg['#type'] === 'link') { + $arg = Link::createFromRoute($arg['#title'], $arg['#url']); + } + /** @var \Drupal\Core\Render\RendererInterface $renderer */ $renderer = \Drupal::service('renderer'); $context = new RenderContext(); - $renderer->executeInRenderContext($context, function() use ($expected, $arg) { - $this->assertSame($expected, theme_autoescape($arg)); + $renderer->executeInRenderContext($context, function () use ($expected, $arg) { + $this->assertSame($expected, theme_escape_and_render($arg)); }); } /** * Provide test examples. */ - public function providerTestThemeAutoescape() { + public function providerTestThemeEscapeAndRender() { return [ ['', ''], ['a', 'a'], ['>', '>'], [SafeString::create('hi'), 'hi'], [SafeString::create(''), ''], + ['hi', Html::escape('hi')], + [['#type' => 'link', '#title' => 'Text', '#url' => ''], 'Text'], [['#markup' => 'hi'], 'hi'], - [['#markup' => ''], 'hi'], - ['', Html::escape('')], + [ + '', + Html::escape('') + ], ]; } + /** + * @expectedException \Exception + */ + public function testThemeEscapeAndRenderNotPrintable() { + theme_escape_and_render(new NonPrintable()); + } + } + +class NonPrintable { }