diff --git a/typo3/sysext/core/Classes/Utility/DebugUtility.php b/typo3/sysext/core/Classes/Utility/DebugUtility.php
index b85ee472fcb062fcf37efbbd171a47b3ecbd1875..6f88a58e776a2fb38dd0e43156aef46e40831ef4 100644
--- a/typo3/sysext/core/Classes/Utility/DebugUtility.php
+++ b/typo3/sysext/core/Classes/Utility/DebugUtility.php
@@ -20,32 +20,45 @@ use TYPO3\CMS\Extbase\Utility\DebuggerUtility;
  */
 class DebugUtility
 {
+    /**
+     * @var bool
+     */
+    static protected $plainTextOutput = true;
+
+    /**
+     * @var bool
+     */
+    static protected $ansiColorUsage = true;
+
     /**
      * Debug
      *
+     * Directly echos out debug information as HTML (or plain in CLI context)
+     *
      * @param string $var
      * @param string $header
      * @param string $group
-     * @return void
      */
     public static function debug($var = '', $header = '', $group = 'Debug')
     {
         // buffer the output of debug if no buffering started before
-        if (ob_get_level() == 0) {
+        if (ob_get_level() === 0) {
             ob_start();
         }
-        $debug = self::convertVariableToString($var);
-        if (TYPO3_MODE === 'BE' && !(TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI)) {
+        if (TYPO3_MODE === 'BE' && !self::isCommandLine()) {
             $tabHeader = $header ?: 'Debug';
+            $debug = self::renderDump($var);
+            $debugPlain = PHP_EOL . self::renderDump($var, '', true, false);
             $script = '
 				(function debug() {
 					var message = ' . GeneralUtility::quoteJSvalue($debug) . ',
-						header = ' . GeneralUtility::quoteJSvalue($header) . ',
+						messagePlain = ' . GeneralUtility::quoteJSvalue($debugPlain) . ',
+						header = ' . GeneralUtility::quoteJSvalue($tabHeader) . ',
 						group = ' . GeneralUtility::quoteJSvalue($group) . ';
-					if (top.TYPO3.DebugConsole) {
+					if (top.TYPO3 && top.TYPO3.DebugConsole) {
 						top.TYPO3.DebugConsole.add(message, header, group);
 					} else {
-						var consoleMessage = [group, header, message].join(" | ");
+						var consoleMessage = [group, header, messagePlain].join(" | ");
 						if (typeof console === "object" && typeof console.log === "function") {
 							console.log(consoleMessage);
 						}
@@ -54,7 +67,7 @@ class DebugUtility
 			';
             echo GeneralUtility::wrapJS($script);
         } else {
-            echo $debug;
+            echo self::renderDump($var);
         }
     }
 
@@ -62,20 +75,12 @@ class DebugUtility
      * Converts a variable to a string
      *
      * @param mixed $variable
-     * @return string
+     * @return string plain, not HTML encoded string
      */
     public static function convertVariableToString($variable)
     {
-        if (is_array($variable)) {
-            $string = self::viewArray($variable);
-        } elseif (is_object($variable)) {
-            $string = json_encode($variable, true);
-        } elseif ((string)$variable !== '') {
-            $string = htmlspecialchars((string)$variable);
-        } else {
-            $string = '| debug |';
-        }
-        return $string;
+        $string = self::renderDump($variable, '', true, false);
+        return $string === '' ? '| debug |' : $string;
     }
 
     /**
@@ -87,7 +92,7 @@ class DebugUtility
      */
     public static function debugInPopUpWindow($debugVariable, $header = 'Debug', $group = 'Debug')
     {
-        $debugString = self::convertVariableToString($debugVariable);
+        $debugString = self::renderDump($debugVariable, sprintf('%s (%s)', $header, $group));
         $script = '
 			(function debug() {
 				var debugMessage = ' . GeneralUtility::quoteJSvalue($debugString) . ',
@@ -129,7 +134,7 @@ class DebugUtility
      * Displays the "path" of the function call stack in a string, using debug_backtrace
      *
      * @param bool $prependFileNames If set to true file names are added to the output
-     * @return string
+     * @return string plain, not HTML encoded string
      */
     public static function debugTrail($prependFileNames = false)
     {
@@ -154,11 +159,10 @@ class DebugUtility
      *
      * @param mixed $rows Array of arrays with similar keys
      * @param string $header Table header
-     * @return void Outputs to browser.
      */
     public static function debugRows($rows, $header = '')
     {
-        self::debug('<pre>' . DebuggerUtility::var_dump($rows, $header, 8, true, false, true), $header . '</pre>');
+        self::debug($rows, $header);
     }
 
     /**
@@ -190,7 +194,7 @@ class DebugUtility
      */
     public static function viewArray($array_in)
     {
-        return '<pre>' . DebuggerUtility::var_dump($array_in, '', 8, true, false, true) . '</pre>';
+        return self::renderDump($array_in);
     }
 
     /**
@@ -202,6 +206,62 @@ class DebugUtility
      */
     public static function printArray($array_in)
     {
-        echo self::viewArray($array_in);
+        echo self::renderDump($array_in);
+    }
+
+    /**
+     * Renders the dump according to the context, either for command line or as HTML output
+     *
+     * @param mixed $variable
+     * @param string $title
+     * @param bool|null $plainText
+     * @param bool|null $ansiColors
+     * @return string
+     */
+    protected static function renderDump($variable, $title = '', $plainText = null, $ansiColors = null)
+    {
+        $plainText = $plainText === null ? self::isCommandLine() && self::$plainTextOutput : $plainText;
+        $ansiColors = $ansiColors === null ? self::isCommandLine() && self::$ansiColorUsage : $ansiColors;
+        return trim(DebuggerUtility::var_dump($variable, $title, 8, $plainText, $ansiColors, true));
+    }
+
+    /**
+     * Checks some constants to determine if we are in CLI context
+     *
+     * @return bool
+     */
+    protected static function isCommandLine()
+    {
+        return (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI) || PHP_SAPI === 'cli';
+    }
+
+    /**
+     * Preset plaintext output
+     *
+     * Warning:
+     * This is NOT a public API method and must not be used in own extensions!
+     * This method is usually only used in tests to preset the output behaviour
+     *
+     * @internal
+     * @param bool $plainTextOutput
+     */
+    public static function usePlainTextOutput($plainTextOutput)
+    {
+        static::$plainTextOutput = $plainTextOutput;
+    }
+
+    /**
+     * Preset ansi color usage
+     *
+     * Warning:
+     * This is NOT a public API method and must not be used in own extensions!
+     * This method is usually only used in tests to preset the ansi color usage
+     *
+     * @internal
+     * @param bool $ansiColorUsage
+     */
+    public static function useAnsiColor($ansiColorUsage)
+    {
+        static::$ansiColorUsage = $ansiColorUsage;
     }
 }
diff --git a/typo3/sysext/core/Tests/Unit/Utility/DebugUtilityTest.php b/typo3/sysext/core/Tests/Unit/Utility/DebugUtilityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..396514acd4525b434646c97e4ead5e89de781c3e
--- /dev/null
+++ b/typo3/sysext/core/Tests/Unit/Utility/DebugUtilityTest.php
@@ -0,0 +1,118 @@
+<?php
+namespace TYPO3\CMS\Core\Tests\Unit\Utility;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Core\Tests\UnitTestCase;
+use TYPO3\CMS\Core\Utility\DebugUtility;
+
+/**
+ * Testcase for class \TYPO3\CMS\Core\Utility\DebugUtility
+ */
+class DebugUtilityTest extends UnitTestCase
+{
+    protected function tearDown()
+    {
+        parent::tearDown();
+        DebugUtility::usePlainTextOutput(true);
+        DebugUtility::useAnsiColor(true);
+    }
+
+    /**
+     * @test
+     */
+    public function debugNotEncodesHtmlInputIfPlainText()
+    {
+        DebugUtility::usePlainTextOutput(true);
+        DebugUtility::useAnsiColor(false);
+
+        ob_start();
+        DebugUtility::debug('<script>alert(\'Hello world!\')</script>');
+        $output = ob_get_contents();
+        ob_end_clean();
+
+        $this->assertContains(
+            '<script>alert(\'Hello world!\')</script>',
+            $output
+        );
+    }
+
+    /**
+     * @test
+     */
+    public function debugEncodesHtmlInputIfNoPlainText()
+    {
+        DebugUtility::usePlainTextOutput(false);
+        DebugUtility::useAnsiColor(false);
+
+        ob_start();
+        DebugUtility::debug('<script>alert(\'Hello world!\')</script>');
+        $output = ob_get_contents();
+        ob_end_clean();
+
+        $this->assertContains(
+            '&lt;script&gt;alert(\'Hello world!\')&lt;/script&gt;',
+            $output
+        );
+    }
+
+    /**
+     * @return array
+     */
+    public function convertVariableToStringReturnsVariableContentDataProvider()
+    {
+        $object = new \stdClass();
+        $object->foo = 42;
+        $object->bar = ['baz'];
+
+        return [
+            'Debug string' => [
+                'Hello world!',
+                '"Hello world!" (12 chars)',
+            ],
+            'Debug array' => [
+                [
+                    'foo',
+                    'bar',
+                    'baz' => [
+                        42,
+                    ],
+                ],
+                'array(3 items)' . PHP_EOL
+. '   0 => "foo" (3 chars)' . PHP_EOL
+. '   1 => "bar" (3 chars)' . PHP_EOL
+. '   baz => array(1 item)' . PHP_EOL
+. '      0 => 42 (integer)',
+            ],
+            'Debug object' => [
+                $object,
+                'stdClass prototype object' . PHP_EOL
+. '   foo => public 42 (integer)' . PHP_EOL
+. '   bar => public array(1 item)' . PHP_EOL
+. '      0 => "baz" (3 chars)'
+            ],
+        ];
+    }
+
+    /**
+     * @test
+     * @dataProvider convertVariableToStringReturnsVariableContentDataProvider
+     * @param mixed $variable
+     * @param string $expected
+     */
+    public function convertVariableToStringReturnsVariableContent($variable, $expected)
+    {
+        $this->assertSame($expected, DebugUtility::convertVariableToString($variable));
+    }
+}
diff --git a/typo3/sysext/extbase/Classes/Utility/DebuggerUtility.php b/typo3/sysext/extbase/Classes/Utility/DebuggerUtility.php
index e7fed4b16a2b3034a14bc7a3b362c0a2a36e5180..f1c15afbe06d7bd680c2c2c3ddccc10d6081d3f0 100644
--- a/typo3/sysext/extbase/Classes/Utility/DebuggerUtility.php
+++ b/typo3/sysext/extbase/Classes/Utility/DebuggerUtility.php
@@ -337,7 +337,7 @@ class DebuggerUtility
                 $property->setAccessible(true);
                 $visibility = ($property->isProtected() ? 'protected' : ($property->isPrivate() ? 'private' : 'public'));
                 if ($plainText) {
-                    $dump .= ' ' . self::ansiEscapeWrap($visibility, '42;30', $ansiColors) . ' ';
+                    $dump .= self::ansiEscapeWrap($visibility, '42;30', $ansiColors) . ' ';
                 } else {
                     $dump .= '<span class="extbase-debug-visibility">' . $visibility . '</span>';
                 }
@@ -427,7 +427,7 @@ class DebuggerUtility
             $css = '
 				<style type=\'text/css\'>
 					.extbase-debugger-tree{position:relative}
-					.extbase-debugger-tree input{position:absolute;top:0;left:0;height:14px;width:14px;margin:0;cursor:pointer;opacity:0;z-index:2}
+					.extbase-debugger-tree input{position:absolute !important;float: none !important;top:0;left:0;height:14px;width:14px;margin:0 !important;cursor:pointer;opacity:0;z-index:2}
 					.extbase-debugger-tree input~.extbase-debug-content{display:none}
 					.extbase-debugger-tree .extbase-debug-header:before{position:relative;top:3px;content:"";padding:0;line-height:10px;height:12px;width:12px;text-align:center;margin:0 3px 0 0;background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkViZW5lXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgMTIgMTIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDEyIDEyOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHN0eWxlIHR5cGU9InRleHQvY3NzIj4uc3Qwe2ZpbGw6Izg4ODg4ODt9PC9zdHlsZT48cGF0aCBpZD0iQm9yZGVyIiBjbGFzcz0ic3QwIiBkPSJNMTEsMTFIMFYwaDExVjExeiBNMTAsMUgxdjloOVYxeiIvPjxnIGlkPSJJbm5lciI+PHJlY3QgeD0iMiIgeT0iNSIgY2xhc3M9InN0MCIgd2lkdGg9IjciIGhlaWdodD0iMSIvPjxyZWN0IHg9IjUiIHk9IjIiIGNsYXNzPSJzdDAiIHdpZHRoPSIxIiBoZWlnaHQ9IjciLz48L2c+PC9zdmc+);display:inline-block}
 					.extbase-debugger-tree input:checked~.extbase-debug-content{display:inline}
diff --git a/typo3/sysext/frontend/Tests/Unit/ContentObject/ContentObjectRendererTest.php b/typo3/sysext/frontend/Tests/Unit/ContentObject/ContentObjectRendererTest.php
index e08c38d9985247ad085d81c5a00a5f333da8fa63..6d2d87bdca69868a97b928287986a6a0885fa031 100755
--- a/typo3/sysext/frontend/Tests/Unit/ContentObject/ContentObjectRendererTest.php
+++ b/typo3/sysext/frontend/Tests/Unit/ContentObject/ContentObjectRendererTest.php
@@ -19,6 +19,7 @@ use TYPO3\CMS\Core\Charset\CharsetConverter;
 use TYPO3\CMS\Core\Core\ApplicationContext;
 use TYPO3\CMS\Core\Log\LogManager;
 use TYPO3\CMS\Core\TypoScript\TemplateService;
+use TYPO3\CMS\Core\Utility\DebugUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Frontend\ContentObject\AbstractContentObject;
 use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
@@ -3006,9 +3007,9 @@ class ContentObjectRendererTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
         $expectedResult = 'array(3items)0=>array(2items)uid=>1(integer)title=>"title1"(6chars)1=>array(2items)uid=>2(integer)title=>"title2"(6chars)2=>array(2items)uid=>3(integer)title=>""(0chars)';
         $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
 
+        DebugUtility::useAnsiColor(false);
         $result = $this->subject->getData('debug:rootLine');
-        $cleanedResult = strip_tags($result);
-        $cleanedResult = str_replace("\r", '', $cleanedResult);
+        $cleanedResult = str_replace("\r", '', $result);
         $cleanedResult = str_replace("\n", '', $cleanedResult);
         $cleanedResult = str_replace("\t", '', $cleanedResult);
         $cleanedResult = str_replace(' ', '', $cleanedResult);
@@ -3031,9 +3032,9 @@ class ContentObjectRendererTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
         $expectedResult = 'array(3items)0=>array(2items)uid=>1(integer)title=>"title1"(6chars)1=>array(2items)uid=>2(integer)title=>"title2"(6chars)2=>array(2items)uid=>3(integer)title=>""(0chars)';
         $GLOBALS['TSFE']->rootLine = $rootline;
 
+        DebugUtility::useAnsiColor(false);
         $result = $this->subject->getData('debug:fullRootLine');
-        $cleanedResult = strip_tags($result);
-        $cleanedResult = str_replace("\r", '', $cleanedResult);
+        $cleanedResult = str_replace("\r", '', $result);
         $cleanedResult = str_replace("\n", '', $cleanedResult);
         $cleanedResult = str_replace("\t", '', $cleanedResult);
         $cleanedResult = str_replace(' ', '', $cleanedResult);
@@ -3054,9 +3055,9 @@ class ContentObjectRendererTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
 
         $expectedResult = 'array(1item)' . $key . '=>"' . $value . '"(' . strlen($value) . 'chars)';
 
+        DebugUtility::useAnsiColor(false);
         $result = $this->subject->getData('debug:data');
-        $cleanedResult = strip_tags($result);
-        $cleanedResult = str_replace("\r", '', $cleanedResult);
+        $cleanedResult = str_replace("\r", '', $result);
         $cleanedResult = str_replace("\n", '', $cleanedResult);
         $cleanedResult = str_replace("\t", '', $cleanedResult);
         $cleanedResult = str_replace(' ', '', $cleanedResult);
@@ -3077,9 +3078,9 @@ class ContentObjectRendererTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
 
         $expectedResult = 'array(1item)' . $key . '=>"' . $value . '"(' . strlen($value) . 'chars)';
 
+        DebugUtility::useAnsiColor(false);
         $result = $this->subject->getData('debug:register');
-        $cleanedResult = strip_tags($result);
-        $cleanedResult = str_replace("\r", '', $cleanedResult);
+        $cleanedResult = str_replace("\r", '', $result);
         $cleanedResult = str_replace("\n", '', $cleanedResult);
         $cleanedResult = str_replace("\t", '', $cleanedResult);
         $cleanedResult = str_replace(' ', '', $cleanedResult);
@@ -3099,9 +3100,9 @@ class ContentObjectRendererTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
 
         $expectedResult = 'array(1item)uid=>' . $uid . '(integer)';
 
+        DebugUtility::useAnsiColor(false);
         $result = $this->subject->getData('debug:page');
-        $cleanedResult = strip_tags($result);
-        $cleanedResult = str_replace("\r", '', $cleanedResult);
+        $cleanedResult = str_replace("\r", '', $result);
         $cleanedResult = str_replace("\n", '', $cleanedResult);
         $cleanedResult = str_replace("\t", '', $cleanedResult);
         $cleanedResult = str_replace(' ', '', $cleanedResult);