diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 5300d76..e6bd4c3 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -514,10 +514,10 @@ function watchdog_exception($type, Exception $exception, $message = NULL, $varia
* drupal_set_message(t('An error occurred and processing did not complete.'), 'error');
* @endcode
*
- * @param string|\Drupal\Component\Utility\SafeStringInterface $message
+ * @param string|array|\Drupal\Component\Utility\SafeStringInterface $message
* (optional) The translated message to be displayed to the user. For
* consistency with other messages, it should begin with a capital letter and
- * end with a period.
+ * end with a period. A render array may also be provided for markup.
* @param string $type
* (optional) The message's type. Defaults to 'status'. These values are
* supported:
@@ -566,6 +566,14 @@ function drupal_set_message($message = NULL, $type = 'status', $repeat = FALSE)
$message = \Drupal\Core\Render\SafeString::create($message);
}
+ // If the message is a render array, render it to a string now to avoid
+ // storing render arrays in $_SESSION, because rendering across requests
+ // may have unpredictable results and some render array functionality
+ // (like assets) should not be supported.
+ if (is_array($message)) {
+ $message = \Drupal::service('renderer')->renderPlain($message);
+ }
+
// Do not use strict type checking so that equivalent string and
// SafeStringInterface objects are detected.
if ($repeat || !in_array($message, $_SESSION['messages'][$type])) {
diff --git a/core/modules/system/src/Tests/Bootstrap/DrupalSetMessageTest.php b/core/modules/system/src/Tests/Bootstrap/DrupalSetMessageTest.php
index 1b63324..3b414af 100644
--- a/core/modules/system/src/Tests/Bootstrap/DrupalSetMessageTest.php
+++ b/core/modules/system/src/Tests/Bootstrap/DrupalSetMessageTest.php
@@ -37,6 +37,15 @@ function testDrupalSetMessage() {
$this->assertUniqueText('Non Duplicated message');
$this->assertNoUniqueText('Duplicated message');
+ // Ensure render arrays are rendered.
+ $this->assertRaw('Render array with markup!');
+ $this->assertUniqueText('Render array with markup!');
+ $this->assertRaw('Render array 2 with markup!');
+
+ // Ensure render arrays with objects are rendered.
+ $this->assertRaw('Render array with SafeString markup!');
+ $this->assertUniqueText('Render array with SafeString markup!');
+
// Ensure SafeString objects are rendered as expected.
$this->assertRaw('SafeString with markup!');
$this->assertUniqueText('SafeString with markup!');
@@ -45,6 +54,7 @@ function testDrupalSetMessage() {
// Ensure when the same message is of different types it is not duplicated.
$this->assertUniqueText('Non duplicate SafeString / string.');
$this->assertNoUniqueText('Duplicate SafeString / string.');
+ $this->assertUniqueText('Duplicate render array / string');
// Ensure that strings that are not marked as safe are escaped.
$this->assertEscaped('Thismarkup will be escaped.');
diff --git a/core/modules/system/tests/modules/system_test/src/Controller/SystemTestController.php b/core/modules/system/tests/modules/system_test/src/Controller/SystemTestController.php
index 15ab478..63cd091 100644
--- a/core/modules/system/tests/modules/system_test/src/Controller/SystemTestController.php
+++ b/core/modules/system/tests/modules/system_test/src/Controller/SystemTestController.php
@@ -114,6 +114,18 @@ public function drupalSetMessageTest() {
drupal_set_message('Duplicated message', 'status', TRUE);
drupal_set_message('Duplicated message', 'status', TRUE);
+ // Add a render array message.
+ drupal_set_message(['#markup' => 'Render array with markup!']);
+ // Test duplicate render arrays.
+ drupal_set_message(['#markup' => 'Render array with markup!']);
+ // Ensure that multiple render array messages work.
+ drupal_set_message(['#markup' => 'Render array 2 with markup!']);
+
+ // Add a render array message containing objects.
+ drupal_set_message(['#markup' => SafeString::create('Render array with SafeString markup!')]);
+ // Test duplicate render array messages.
+ drupal_set_message(['#markup' => SafeString::create('Render array with SafeString markup!')]);
+
// Add a SafeString message.
drupal_set_message(SafeString::create('SafeString with markup!'));
// Test duplicate SafeString messages.
@@ -126,6 +138,8 @@ public function drupalSetMessageTest() {
drupal_set_message('Non duplicate SafeString / string.');
drupal_set_message(SafeString::create('Duplicate SafeString / string.'), 'status', TRUE);
drupal_set_message('Duplicate SafeString / string.', 'status', TRUE);
+ drupal_set_message(['#markup' => 'Duplicate render array / string']);
+ drupal_set_message('Duplicate render array / string');
// Test auto-escape of non safe strings.
drupal_set_message('Thismarkup will be escaped.');