diff --git a/core/lib/Drupal/Core/Render/Element/Markup.php b/core/lib/Drupal/Core/Render/Element/Markup.php
index ffa87ed..eadf2fc 100644
--- a/core/lib/Drupal/Core/Render/Element/Markup.php
+++ b/core/lib/Drupal/Core/Render/Element/Markup.php
@@ -125,21 +125,43 @@ public static function ensureMarkupIsSafe(array $elements) {
       return $elements;
     }
 
-    $strategy = isset($elements['#safe_strategy']) ? $elements['#safe_strategy'] : static::SAFE_STRATEGY_FILTER;
-    if (SafeMarkup::isSafe($elements['#markup'])) {
-      // Nothing to do as #markup is already marked as safe.
-      return $elements;
-    }
-    elseif ($strategy == static::SAFE_STRATEGY_ESCAPE) {
-      $markup = HtmlUtility::escape($elements['#markup']);
+    $multiple_elements = FALSE;
+    if (!is_array($elements['#markup'])) {
+      $markups[] = $elements['#markup'];
     }
     else {
+      $markups = $elements['#markup'];
+      $multiple_elements = count($markups) > 1;
+    }
+
+    $strategy = isset($elements['#safe_strategy']) ? $elements['#safe_strategy'] : static::SAFE_STRATEGY_FILTER;
+    if ($strategy != static::SAFE_STRATEGY_ESCAPE) {
       // The default behaviour is to XSS filter using the admin tag list.
       $tags = isset($elements['#allowed_tags']) ? $elements['#allowed_tags'] : Xss::getAdminTagList();
-      $markup = Xss::filter($elements['#markup'], $tags);
+    }
+    foreach($markups as $key => $markup) {
+      if (SafeMarkup::isSafe($markup)) {
+        // Nothing to do as #markup is already marked as safe.
+        if (!$multiple_elements) {
+          return $elements;
+        }
+        continue;
+      }
+      elseif ($strategy == static::SAFE_STRATEGY_ESCAPE) {
+        $markups[$key] = HtmlUtility::escape($markup);
+      }
+      else {
+        $markups[$key] = Xss::filter($markup, $tags);
+      }
+    }
+
+    // Ensure the separator is safe.
+    $separator = isset($elements['#separator']) ? $elements['#separator'] : '';
+    if ($separator !== '' && !SafeMarkup::isSafe($separator)) {
+      $separator = HtmlUtility::escape($separator);
     }
 
-    $elements['#markup'] = SafeString::create($markup);
+    $elements['#markup'] = SafeString::create(implode($separator, $markups));
 
     return $elements;
   }
diff --git a/core/tests/Drupal/Tests/Core/Render/RendererTest.php b/core/tests/Drupal/Tests/Core/Render/RendererTest.php
index c7d2ad4..9ff0546 100644
--- a/core/tests/Drupal/Tests/Core/Render/RendererTest.php
+++ b/core/tests/Drupal/Tests/Core/Render/RendererTest.php
@@ -60,7 +60,7 @@ public function testRenderBasic($build, $expected, callable $setup_code = NULL)
       $setup_code();
     }
 
-    if (isset($build['#markup'])) {
+    if (isset($build['#markup']) && !is_array($build['#markup'])) {
       $this->assertFalse(SafeMarkup::isSafe($build['#markup']), 'The #markup value is not marked safe before rendering.');
     }
     $render_output = $this->renderer->renderRoot($build);
@@ -141,6 +141,42 @@ public function providerTestRenderBasic() {
       '#children' => 'foo',
       'child' => ['#markup' => 'bar'],
     ], 'foo'];
+    // #markup array based renderable array.
+    $data[] = [[
+      '#markup' => ['foo', 'bar'],
+    ], 'foobar'];
+    // #markup array based renderable array that will be escaped.
+    $data[] = [[
+      '#markup' => ['<em>foo</em>', '<em>bar</em>'],
+      '#safe_strategy' => Markup::SAFE_STRATEGY_ESCAPE
+    ], '&lt;em&gt;foo&lt;/em&gt;&lt;em&gt;bar&lt;/em&gt;'];
+    // #markup array based renderable array where one element will be escaped.
+    $data[] = [[
+      '#markup' => [SafeString::create('<em>foo</em>'), '<em>bar</em>'],
+      '#safe_strategy' => Markup::SAFE_STRATEGY_ESCAPE
+    ], '<em>foo</em>&lt;em&gt;bar&lt;/em&gt;'];
+    // #markup array based renderable array where elements will be filter using
+    // the admin filter.
+    $data[] = [[
+      '#markup' => ['<em>foo</em>', '<em><script>alert();</script>bar</em>'],
+    ], '<em>foo</em><em>alert();bar</em>'];
+    // #markup array based renderable array where elements will be filter using
+    // the admin filter.
+    $data[] = [[
+      '#markup' => ['<em>foo</em>', '<em><strong>bar</strong></em>'],
+      '#allowed_tags' => ['strong']
+    ], 'foo<strong>bar</strong>'];
+    // #markup array based renderable array using a separator.
+    $data[] = [[
+      '#markup' => ['one', 'two', 'three'],
+      '#separator' => ', '
+    ], 'one, two, three'];
+    // #markup array based renderable array using a separator that is escaped.
+    $data[] = [[
+      '#markup' => ['one', 'two', 'three'],
+      '#separator' => '</p><p>'
+    ], 'one&lt;/p&gt;&lt;p&gt;two&lt;/p&gt;&lt;p&gt;three'];
+
 
     // Part 2: render arrays using #theme and #theme_wrappers.
 
