diff --git a/core/includes/common.inc b/core/includes/common.inc
index 1581de6..88f16fd 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -20,6 +20,7 @@
use Drupal\Component\Utility\String;
use Drupal\Component\Utility\Tags;
use Drupal\Component\Utility\UrlHelper;
+use Drupal\Component\Utility\Xss;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Render\RenderStackFrame;
@@ -2765,6 +2766,22 @@ function drupal_render(&$elements, $is_recursive_call = FALSE) {
$elements += element_info($elements['#type']);
}
+ // Filtering keys which are expected to contain HTML.
+ $markup_keys = array(
+ '#description',
+ '#field_prefix',
+ '#field_suffix',
+ '#prefix',
+ '#suffix',
+ );
+ foreach ($markup_keys as $key) {
+ // If it's not scalar it can deal with itself through __toString()
+ // or drupal_render().
+ if (!empty($elements[$key]) && is_scalar($elements[$key]) && !SafeMarkup::isSafe($elements[$key])) {
+ $elements[$key] = Xss::filterAdmin($elements[$key]);
+ }
+ }
+
// Make any final changes to the element before it is rendered. This means
// that the $element or the children can be altered or corrected before the
// element is rendered into the final text.
@@ -2896,6 +2913,7 @@ function drupal_render(&$elements, $is_recursive_call = FALSE) {
// #cache is disabled, #cache is enabled, there is a cache hit or miss.
$prefix = isset($elements['#prefix']) ? $elements['#prefix'] : '';
$suffix = isset($elements['#suffix']) ? $elements['#suffix'] : '';
+
$elements['#markup'] = $prefix . $elements['#children'] . $suffix;
// We've rendered this element (and its subtree!), now update the stack.
diff --git a/core/modules/field_ui/src/Tests/FieldUiTestBase.php b/core/modules/field_ui/src/Tests/FieldUiTestBase.php
index 962acec..314cf5b 100644
--- a/core/modules/field_ui/src/Tests/FieldUiTestBase.php
+++ b/core/modules/field_ui/src/Tests/FieldUiTestBase.php
@@ -105,6 +105,7 @@ function fieldUIAddExistingField($bundle_path, $initial_edit, $field_edit = arra
// First step : 'Re-use existing field' on the 'Manage fields' page.
$this->drupalPostForm("$bundle_path/fields", $initial_edit, t('Save'));
+ $this->assertNoRaw('<', 'The page does not have double escaped HTML tags.');
// Second step : 'Field settings' form.
$this->drupalPostForm(NULL, $field_edit, t('Save settings'));
diff --git a/core/modules/locale/src/Form/ImportForm.php b/core/modules/locale/src/Form/ImportForm.php
index eda1567..d9a811c 100644
--- a/core/modules/locale/src/Form/ImportForm.php
+++ b/core/modules/locale/src/Form/ImportForm.php
@@ -103,18 +103,22 @@ public function buildForm(array $form, FormStateInterface $form_state) {
'file_validate_extensions' => array('po'),
'file_validate_size' => array(file_upload_max_size()),
);
+
+ $file_description = array(
+ '#theme' => 'file_upload_help',
+ '#description' => $this->t('A Gettext Portable Object file.'),
+ '#upload_validators' => $validators,
+ );
+
$form['file'] = array(
'#type' => 'file',
'#title' => $this->t('Translation file'),
- '#description' => array(
- '#theme' => 'file_upload_help',
- '#description' => $this->t('A Gettext Portable Object file.'),
- '#upload_validators' => $validators,
- ),
+ '#description' => drupal_render($file_description),
'#size' => 50,
'#upload_validators' => $validators,
'#attributes' => array('class' => array('file-import-input')),
);
+
$form['langcode'] = array(
'#type' => 'select',
'#title' => $this->t('Language'),
diff --git a/core/modules/options/src/Tests/OptionsFieldUITest.php b/core/modules/options/src/Tests/OptionsFieldUITest.php
index e3b4684..40343bf 100644
--- a/core/modules/options/src/Tests/OptionsFieldUITest.php
+++ b/core/modules/options/src/Tests/OptionsFieldUITest.php
@@ -278,6 +278,7 @@ protected function createOptionsField($type) {
function assertAllowedValuesInput($input_string, $result, $message) {
$edit = array('field_storage[settings][allowed_values]' => $input_string);
$this->drupalPostForm($this->admin_path, $edit, t('Save field settings'));
+ $this->assertNoRaw('<', 'The page does not have double escaped HTML tags.');
if (is_string($result)) {
$this->assertText($result, $message);
diff --git a/core/modules/rdf/rdf.module b/core/modules/rdf/rdf.module
index f407e83..5ffd203 100644
--- a/core/modules/rdf/rdf.module
+++ b/core/modules/rdf/rdf.module
@@ -506,7 +506,7 @@ function rdf_preprocess_comment(&$variables) {
'#theme' => 'rdf_metadata',
'#metadata' => $variables['rdf_metadata_attributes'],
);
- $variables['content']['comment_body']['#prefix'] = drupal_render($rdf_metadata) . $variables['content']['comment_body']['#prefix'];
+ $variables['content']['comment_body']['#prefix'] = SafeMarkup::set(drupal_render($rdf_metadata) . $variables['content']['comment_body']['#prefix']);
}
}
diff --git a/core/modules/system/src/Tests/Common/RenderTest.php b/core/modules/system/src/Tests/Common/RenderTest.php
index d07085c..d1bbf39 100644
--- a/core/modules/system/src/Tests/Common/RenderTest.php
+++ b/core/modules/system/src/Tests/Common/RenderTest.php
@@ -9,6 +9,7 @@
use Drupal\Component\Serialization\Json;
use Drupal\Component\Utility\Html;
+use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Render\Element;
use Drupal\simpletest\DrupalUnitTestBase;
@@ -782,8 +783,8 @@ function testDrupalRenderRenderCachePlaceholder() {
),
),
'#markup' => $placeholder,
- '#prefix' => '',
- '#suffix' => ''
+ '#prefix' => SafeMarkup::set(''),
+ '#suffix' => SafeMarkup::set(''),
);
$expected_output = '' . $context['bar'] . '';