diff --git a/src/Illuminate/Foundation/resources/exceptions/renderer/components/query.blade.php b/src/Illuminate/Foundation/resources/exceptions/renderer/components/query.blade.php
index 2615ad130dff..99c6f9099865 100644
--- a/src/Illuminate/Foundation/resources/exceptions/renderer/components/query.blade.php
+++ b/src/Illuminate/Foundation/resources/exceptions/renderer/components/query.blade.php
@@ -110,7 +110,7 @@ class="border border-neutral-200 dark:border-none bg-white dark:bg-white/[3%] ro
language="sql"
truncate
class="min-w-0"
- data-tippy-content="{{ $sql }}"
+ data-tippy-content="{{ nl2br($sql) }}"
/>
{{ $time }}ms
diff --git a/tests/Integration/Foundation/Exceptions/RenderBladeFilesTest.php b/tests/Integration/Foundation/Exceptions/RenderBladeFilesTest.php
new file mode 100644
index 000000000000..a65605c5b990
--- /dev/null
+++ b/tests/Integration/Foundation/Exceptions/RenderBladeFilesTest.php
@@ -0,0 +1,77 @@
+resolve('blade')->getCompiler()->withoutComponentTags();
+ });
+ }
+
+ public function testFormattedSourceTooltipRendersMultilineSafely(): void
+ {
+ $frame = new class
+ {
+ public function class() { return null; }
+ public function previous() { return null; }
+ public function source() { return "Foo::bar(1)\nAnother line"; }
+ };
+
+ $path = package_path('src/Illuminate/Foundation/resources/exceptions/renderer/components/formatted-source.blade.php');
+
+ $html = (string) $this->app['view']->file($path, ['frame' => $frame])->render();
+
+ $this->assertStringContainsString('data-tippy-content="', $html);
+ $this->assertStringNotContainsString('
'mysql', 'sql' => $sql, 'time' => 1.23 ]];
+
+ $path = package_path('src/Illuminate/Foundation/resources/exceptions/renderer/components/query.blade.php');
+
+ $html = (string) $this->app['view']->file($path, ['queries' => $queries])->render();
+
+ $this->assertStringContainsString('data-tippy-content="', $html);
+ $this->assertMatchesRegularExpression('/<br\s*\/?>/', $html);
+ }
+
+ public function testRequestHeaderTooltipRendersMultilineSafely(): void
+ {
+ $headers = [ 'X-Test' => "A\nB" ];
+
+ $path = package_path('src/Illuminate/Foundation/resources/exceptions/renderer/components/request-header.blade.php');
+
+ $html = (string) $this->app['view']->file($path, ['headers' => $headers])->render();
+
+ $this->assertStringContainsString('data-tippy-content="', $html);
+ $this->assertStringNotContainsString('
assertStringContainsString('<script>bad()</script>', $html);
+ }
+
+ public function testRoutingTooltipRendersMultilineSafely(): void
+ {
+ $routing = [ 'URI' => "users/1\nedit" ];
+
+ $path = package_path('src/Illuminate/Foundation/resources/exceptions/renderer/components/routing.blade.php');
+
+ $html = (string) $this->app['view']->file($path, ['routing' => $routing])->render();
+
+ $this->assertStringContainsString('data-tippy-content="', $html);
+ $this->assertStringNotContainsString('