diff --git a/src/Symfony/Bridge/Twig/ErrorRenderer/TwigErrorRenderer.php b/src/Symfony/Bridge/Twig/ErrorRenderer/TwigErrorRenderer.php index f624720b7775..400a0471e58b 100644 --- a/src/Symfony/Bridge/Twig/ErrorRenderer/TwigErrorRenderer.php +++ b/src/Symfony/Bridge/Twig/ErrorRenderer/TwigErrorRenderer.php @@ -25,7 +25,7 @@ */ class TwigErrorRenderer implements ErrorRendererInterface { - private HtmlErrorRenderer $fallbackErrorRenderer; + private ErrorRendererInterface $fallbackErrorRenderer; private \Closure|bool $debug; /** @@ -33,7 +33,7 @@ class TwigErrorRenderer implements ErrorRendererInterface */ public function __construct( private Environment $twig, - ?HtmlErrorRenderer $fallbackErrorRenderer = null, + ?ErrorRendererInterface $fallbackErrorRenderer = null, bool|callable $debug = false, ) { $this->fallbackErrorRenderer = $fallbackErrorRenderer ?? new HtmlErrorRenderer(); diff --git a/src/Symfony/Bridge/Twig/Tests/ErrorRenderer/TwigErrorRendererTest.php b/src/Symfony/Bridge/Twig/Tests/ErrorRenderer/TwigErrorRendererTest.php index 9febc61e6188..1d4f9f3506cb 100644 --- a/src/Symfony/Bridge/Twig/Tests/ErrorRenderer/TwigErrorRendererTest.php +++ b/src/Symfony/Bridge/Twig/Tests/ErrorRenderer/TwigErrorRendererTest.php @@ -13,7 +13,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Bridge\Twig\ErrorRenderer\TwigErrorRenderer; -use Symfony\Component\ErrorHandler\ErrorRenderer\HtmlErrorRenderer; +use Symfony\Component\ErrorHandler\ErrorRenderer\CliErrorRenderer; use Symfony\Component\ErrorHandler\Exception\FlattenException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Twig\Environment; @@ -21,36 +21,32 @@ class TwigErrorRendererTest extends TestCase { - public function testFallbackToNativeRendererIfDebugOn() + public function tesFallbackRenderer() { - $exception = new \Exception(); - $twig = $this->createMock(Environment::class); - $nativeRenderer = $this->createMock(HtmlErrorRenderer::class); - $nativeRenderer - ->expects($this->once()) - ->method('render') - ->with($exception) - ; - - (new TwigErrorRenderer($twig, $nativeRenderer, true))->render(new \Exception()); + $customRenderer = new class implements ErrorRendererInterface { + public function render(\Throwable $exception): FlattenException + { + return 'This is a custom error renderer.'; + } + }; + + $this->assertSame('This is a custom error renderer.', (new TwigErrorRenderer($twig, $customRenderer, true))->render(new \Exception())); } - public function testFallbackToNativeRendererIfCustomTemplateNotFound() + public function testCliRenderer() { $exception = new NotFoundHttpException(); - $twig = new Environment(new ArrayLoader([])); - $nativeRenderer = $this->createMock(HtmlErrorRenderer::class); - $nativeRenderer - ->expects($this->once()) - ->method('render') - ->with($exception) - ->willReturn(FlattenException::createFromThrowable($exception)) - ; + $exception = (new TwigErrorRenderer($twig, new CliErrorRenderer(), false))->render($exception); + + $exceptionHeaders = $exception->getHeaders(); + if (isset($exceptionHeaders['Content-Type'])) { + $this->assertSame('text/plain', $exceptionHeaders['Content-Type'], 'The exception does not return HTML contents (to prevent potential XSS vulnerabilities)'); + } - (new TwigErrorRenderer($twig, $nativeRenderer, false))->render($exception); + $this->assertStringNotContainsString('', $exception->getAsString(), 'The exception does not include elements of the HTML exception page'); } public function testRenderCustomErrorTemplate() diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ErrorRendererPass.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ErrorRendererPass.php new file mode 100644 index 000000000000..59f5d7db3519 --- /dev/null +++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ErrorRendererPass.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\TwigBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\ErrorHandler\ErrorRenderer\CliErrorRenderer; + +/** + * @author Javier Eguiluz + * @internal + */ +class ErrorRendererPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container): void + { + // in the 'test' environment, use the CLI error renderer as the default one + if ($container->hasDefinition('test.client')) { + $container->getDefinition('twig.error_renderer.html') + ->setArgument(1, new Definition(CliErrorRenderer::class)); + } + } +} diff --git a/src/Symfony/Bundle/TwigBundle/TwigBundle.php b/src/Symfony/Bundle/TwigBundle/TwigBundle.php index 5ff13b1bc868..460a1bbe3ebf 100644 --- a/src/Symfony/Bundle/TwigBundle/TwigBundle.php +++ b/src/Symfony/Bundle/TwigBundle/TwigBundle.php @@ -11,6 +11,7 @@ namespace Symfony\Bundle\TwigBundle; +use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\ErrorRendererPass; use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\ExtensionPass; use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\RuntimeLoaderPass; use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\TwigEnvironmentPass; @@ -36,6 +37,7 @@ public function build(ContainerBuilder $container): void $container->addCompilerPass(new TwigEnvironmentPass()); $container->addCompilerPass(new TwigLoaderPass()); $container->addCompilerPass(new RuntimeLoaderPass(), PassConfig::TYPE_BEFORE_REMOVING); + $container->addCompilerPass(new ErrorRendererPass()); } public function registerCommands(Application $application): void diff --git a/src/Symfony/Bundle/TwigBundle/composer.json b/src/Symfony/Bundle/TwigBundle/composer.json index 3dc098094382..49196ecc5fb8 100644 --- a/src/Symfony/Bundle/TwigBundle/composer.json +++ b/src/Symfony/Bundle/TwigBundle/composer.json @@ -20,7 +20,7 @@ "composer-runtime-api": ">=2.1", "symfony/config": "^6.4|^7.0", "symfony/dependency-injection": "^6.4|^7.0", - "symfony/twig-bridge": "^6.4|^7.0", + "symfony/twig-bridge": "^7.2", "symfony/http-foundation": "^6.4|^7.0", "symfony/http-kernel": "^6.4|^7.0", "twig/twig": "^3.12|^4.0" diff --git a/src/Symfony/Component/ErrorHandler/ErrorRenderer/CliErrorRenderer.php b/src/Symfony/Component/ErrorHandler/ErrorRenderer/CliErrorRenderer.php index c414c83077f7..8a4a3ea5601b 100644 --- a/src/Symfony/Component/ErrorHandler/ErrorRenderer/CliErrorRenderer.php +++ b/src/Symfony/Component/ErrorHandler/ErrorRenderer/CliErrorRenderer.php @@ -40,7 +40,7 @@ protected function supportsColors(): bool } }; - return FlattenException::createFromThrowable($exception) + return FlattenException::createFromThrowable($exception, headers: ['Content-Type' => 'text/plain']) ->setAsString($dumper->dump($cloner->cloneVar($exception), true)); } } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy