diff --git a/src/Symfony/Bridge/Twig/Extension/CodeExtension.php b/src/Symfony/Bridge/Twig/Extension/CodeExtension.php
index 353bd84f3f6f7..fe2246e68b21a 100644
--- a/src/Symfony/Bridge/Twig/Extension/CodeExtension.php
+++ b/src/Symfony/Bridge/Twig/Extension/CodeExtension.php
@@ -97,8 +97,10 @@ public function formatArgs(array $args): string
$formattedValue = ''.strtolower(htmlspecialchars(var_export($item[1], true), \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset)).'';
} elseif ('resource' === $item[0]) {
$formattedValue = 'resource';
+ } elseif (preg_match('/[^\x07-\x0D\x1B\x20-\xFF]/', $item[1])) {
+ $formattedValue = 'binary string';
} else {
- $formattedValue = str_replace("\n", '', htmlspecialchars(var_export($item[1], true), \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset));
+ $formattedValue = str_replace("\n", '', $this->escape(var_export($item[1], true)));
}
$result[] = \is_int($key) ? $formattedValue : sprintf("'%s' => %s", htmlspecialchars($key, \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset), $formattedValue);
diff --git a/src/Symfony/Component/ErrorHandler/ErrorRenderer/HtmlErrorRenderer.php b/src/Symfony/Component/ErrorHandler/ErrorRenderer/HtmlErrorRenderer.php
index 92434b8e94506..08685fa21e867 100644
--- a/src/Symfony/Component/ErrorHandler/ErrorRenderer/HtmlErrorRenderer.php
+++ b/src/Symfony/Component/ErrorHandler/ErrorRenderer/HtmlErrorRenderer.php
@@ -173,6 +173,8 @@ private function formatArgs(array $args): string
$formattedValue = ''.strtolower(var_export($item[1], true)).'';
} elseif ('resource' === $item[0]) {
$formattedValue = 'resource';
+ } elseif (preg_match('/[^\x07-\x0D\x1B\x20-\xFF]/', $item[1])) {
+ $formattedValue = 'binary string';
} else {
$formattedValue = str_replace("\n", '', $this->escape(var_export($item[1], true)));
}
diff --git a/src/Symfony/Component/ErrorHandler/Tests/ErrorRenderer/HtmlErrorRendererTest.php b/src/Symfony/Component/ErrorHandler/Tests/ErrorRenderer/HtmlErrorRendererTest.php
index 6680b95a0cc3d..4ab602337159b 100644
--- a/src/Symfony/Component/ErrorHandler/Tests/ErrorRenderer/HtmlErrorRendererTest.php
+++ b/src/Symfony/Component/ErrorHandler/Tests/ErrorRenderer/HtmlErrorRendererTest.php
@@ -54,4 +54,45 @@ public static function getRenderData(): iterable
$expectedNonDebug,
];
}
+
+ public function testRendersStackWithoutBinaryStrings()
+ {
+ if (\PHP_VERSION_ID >= 70400) {
+ // make sure method arguments are available in stack traces (see https://www.php.net/manual/en/ini.core.php)
+ ini_set('zend.exception_ignore_args', false);
+ }
+
+ $binaryData = file_get_contents(__DIR__ . '/../Fixtures/pixel.png');
+ $exception = $this->getRuntimeException($binaryData);
+
+ $rendered = (new HtmlErrorRenderer(true))->render($exception)->getAsString();
+
+ $this->assertStringContainsString(
+ "buildRuntimeException('FooException')",
+ $rendered,
+ '->render() contains the method call with "FooException"'
+ );
+
+ $this->assertStringContainsString(
+ 'getRuntimeException(binary string)',
+ $rendered,
+ '->render() contains the method call with "binary string" replacement'
+ );
+
+ $this->assertStringContainsString(
+ 'binary string',
+ $rendered,
+ '->render() returns the HTML content with "binary string" replacement'
+ );
+ }
+
+ private function getRuntimeException(string $unusedArgument): \RuntimeException
+ {
+ return $this->buildRuntimeException('FooException');
+ }
+
+ private function buildRuntimeException(string $message): \RuntimeException
+ {
+ return new \RuntimeException($message);
+ }
}
diff --git a/src/Symfony/Component/ErrorHandler/Tests/Fixtures/pixel.png b/src/Symfony/Component/ErrorHandler/Tests/Fixtures/pixel.png
new file mode 100644
index 0000000000000..35269f61fcde4
Binary files /dev/null and b/src/Symfony/Component/ErrorHandler/Tests/Fixtures/pixel.png differ