Skip to content

Commit fecda76

Browse files
faisuccrynoboneavosalmon
authored
[12.x] Render newlines in query tooltip (#57310)
* Escape multiline tooltip content in exceptions renderer (nl2br(e())) * Create RenderBladeFilesTest.php * Update RenderBladeFilesTest.php * Refactor setUp method to defineEnvironment method * Update src/Illuminate/Foundation/resources/exceptions/renderer/components/request-header.blade.php * rename test files * Render multiline query tooltips safely with nl2br(e(...)) * Format * adjustments --------- Co-authored-by: Mior Muhammad Zaki <[email protected]> Co-authored-by: Ryuta Hamasaki <[email protected]>
1 parent ea11311 commit fecda76

File tree

2 files changed

+78
-1
lines changed

2 files changed

+78
-1
lines changed

src/Illuminate/Foundation/resources/exceptions/renderer/components/query.blade.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ class="border border-neutral-200 dark:border-none bg-white dark:bg-white/[3%] ro
110110
language="sql"
111111
truncate
112112
class="min-w-0"
113-
data-tippy-content="{{ $sql }}"
113+
data-tippy-content="{{ nl2br($sql) }}"
114114
/>
115115
</div>
116116
<div class="text-neutral-500 dark:text-neutral-200 text-right flex-shrink-0">{{ $time }}ms</div>
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
3+
namespace Illuminate\Tests\Integration\Foundation\Exceptions\Renderer;
4+
5+
use Orchestra\Testbench\Attributes\WithConfig;
6+
use Orchestra\Testbench\TestCase;
7+
8+
use function Orchestra\Testbench\after_resolving;
9+
use function Orchestra\Testbench\package_path;
10+
11+
#[WithConfig('app.debug', true)]
12+
class RenderBladeFilesTest extends TestCase
13+
{
14+
protected function defineEnvironment($app)
15+
{
16+
after_resolving($app, 'view.engine.resolver', function ($resolver) {
17+
$resolver->resolve('blade')->getCompiler()->withoutComponentTags();
18+
});
19+
}
20+
21+
public function testFormattedSourceTooltipRendersMultilineSafely(): void
22+
{
23+
$frame = new class
24+
{
25+
public function class() { return null; }
26+
public function previous() { return null; }
27+
public function source() { return "Foo::bar(1)\nAnother line"; }
28+
};
29+
30+
$path = package_path('src/Illuminate/Foundation/resources/exceptions/renderer/components/formatted-source.blade.php');
31+
32+
$html = (string) $this->app['view']->file($path, ['frame' => $frame])->render();
33+
34+
$this->assertStringContainsString('data-tippy-content="', $html);
35+
$this->assertStringNotContainsString('<br', $html);
36+
}
37+
38+
public function testQueryTooltipRendersMultilineSafely(): void
39+
{
40+
$sql = "SELECT * FROM tests\nWHERE id = 1";
41+
$queries = [[ 'connectionName' => 'mysql', 'sql' => $sql, 'time' => 1.23 ]];
42+
43+
$path = package_path('src/Illuminate/Foundation/resources/exceptions/renderer/components/query.blade.php');
44+
45+
$html = (string) $this->app['view']->file($path, ['queries' => $queries])->render();
46+
47+
$this->assertStringContainsString('data-tippy-content="', $html);
48+
$this->assertMatchesRegularExpression('/&lt;br\s*\/?&gt;/', $html);
49+
}
50+
51+
public function testRequestHeaderTooltipRendersMultilineSafely(): void
52+
{
53+
$headers = [ 'X-Test' => "A\nB<script>bad()</script>" ];
54+
55+
$path = package_path('src/Illuminate/Foundation/resources/exceptions/renderer/components/request-header.blade.php');
56+
57+
$html = (string) $this->app['view']->file($path, ['headers' => $headers])->render();
58+
59+
$this->assertStringContainsString('data-tippy-content="', $html);
60+
$this->assertStringNotContainsString('<br', $html);
61+
$this->assertStringContainsString('&lt;script&gt;bad()&lt;/script&gt;', $html);
62+
}
63+
64+
public function testRoutingTooltipRendersMultilineSafely(): void
65+
{
66+
$routing = [ 'URI' => "users/1\nedit" ];
67+
68+
$path = package_path('src/Illuminate/Foundation/resources/exceptions/renderer/components/routing.blade.php');
69+
70+
$html = (string) $this->app['view']->file($path, ['routing' => $routing])->render();
71+
72+
$this->assertStringContainsString('data-tippy-content="', $html);
73+
$this->assertStringNotContainsString('<br', $html);
74+
}
75+
}
76+
77+

0 commit comments

Comments
 (0)