Skip to content

Commit ec51a66

Browse files
jbrabandcrynobone
andauthored
[11.x] Fix EncodedHtmlString to ignore instance of HtmlString (#55543)
* fix html encoding for 3 more mail component templates * add tests Signed-off-by: Mior Muhammad Zaki <[email protected]> * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * `Markdown::parse()` returns `HtmlString()` so that should be enough to avoid double encoding Signed-off-by: Mior Muhammad Zaki <[email protected]> * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * wip * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> --------- Signed-off-by: Mior Muhammad Zaki <[email protected]> Co-authored-by: Mior Muhammad Zaki <[email protected]>
1 parent 7358937 commit ec51a66

File tree

6 files changed

+145
-3
lines changed

6 files changed

+145
-3
lines changed

src/Illuminate/Mail/resources/views/html/panel.blade.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<table width="100%" cellpadding="0" cellspacing="0" role="presentation">
55
<tr>
66
<td class="panel-item">
7-
{!! Illuminate\Mail\Markdown::parse($slot) !!}
7+
{{ Illuminate\Mail\Markdown::parse($slot) }}
88
</td>
99
</tr>
1010
</table>

src/Illuminate/Support/EncodedHtmlString.php

+27-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,19 @@
22

33
namespace Illuminate\Support;
44

5+
use BackedEnum;
6+
use Illuminate\Contracts\Support\DeferringDisplayableValue;
7+
use Illuminate\Contracts\Support\Htmlable;
8+
59
class EncodedHtmlString extends HtmlString
610
{
11+
/**
12+
* The HTML string.
13+
*
14+
* @var \Illuminate\Contracts\Support\DeferringDisplayableValue|\Illuminate\Contracts\Support\Htmlable|\BackedEnum|string|int|float|null
15+
*/
16+
protected $html;
17+
718
/**
819
* The callback that should be used to encode the HTML strings.
920
*
@@ -14,7 +25,7 @@ class EncodedHtmlString extends HtmlString
1425
/**
1526
* Create a new encoded HTML string instance.
1627
*
17-
* @param string $html
28+
* @param \Illuminate\Contracts\Support\DeferringDisplayableValue|\Illuminate\Contracts\Support\Htmlable|\BackedEnum|string|int|float|null $html
1829
* @param bool $doubleEncode
1930
* @return void
2031
*/
@@ -48,9 +59,23 @@ public static function convert($value, bool $withQuote = true, bool $doubleEncod
4859
#[\Override]
4960
public function toHtml()
5061
{
62+
$value = $this->html;
63+
64+
if ($value instanceof DeferringDisplayableValue) {
65+
$value = $value->resolveDisplayableValue();
66+
}
67+
68+
if ($value instanceof Htmlable) {
69+
return $value->toHtml();
70+
}
71+
72+
if ($value instanceof BackedEnum) {
73+
$value = $value->value;
74+
}
75+
5176
return (static::$encodeUsingFactory ?? function ($value, $doubleEncode) {
5277
return static::convert($value, doubleEncode: $doubleEncode);
53-
})($this->html, $this->doubleEncode);
78+
})($value, $this->doubleEncode);
5479
}
5580

5681
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<x-mail::message subcopy="This is a subcopy">
2+
3+
<x-mail::table>
4+
*Hi* {{ $user->name }}
5+
6+
| Laravel | Table | Example |
7+
| ------------- | :-----------: | ------------: |
8+
| Col 2 is | Centered | $10 |
9+
| Col 3 is | Right-Aligned | $20 |
10+
</x-mail::table>
11+
12+
</x-mail::message>

tests/Integration/Mail/MailableWithSecuredEncodingTest.php

+50
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,56 @@ public function build()
116116
$mailable->assertSeeInHtml($expected, false);
117117
}
118118

119+
#[WithMigration]
120+
#[DataProvider('markdownEncodedTemplateDataProvider')]
121+
public function testItCanAssertMarkdownEncodedStringUsingTemplateWithTable($given, $expected)
122+
{
123+
$user = UserFactory::new()->create([
124+
'name' => $given,
125+
]);
126+
127+
$mailable = new class($user) extends Mailable
128+
{
129+
public $theme = 'taylor';
130+
131+
public function __construct(public User $user)
132+
{
133+
//
134+
}
135+
136+
public function build()
137+
{
138+
return $this->markdown('table-with-template');
139+
}
140+
};
141+
142+
$mailable->assertSeeInHtml($expected, false);
143+
$mailable->assertSeeInHtml('<p>This is a subcopy</p>', false);
144+
$mailable->assertSeeInHtml(<<<'TABLE'
145+
<table>
146+
<thead>
147+
<tr>
148+
<th>Laravel</th>
149+
<th align="center">Table</th>
150+
<th align="right">Example</th>
151+
</tr>
152+
</thead>
153+
<tbody>
154+
<tr>
155+
<td>Col 2 is</td>
156+
<td align="center">Centered</td>
157+
<td align="right">$10</td>
158+
</tr>
159+
<tr>
160+
<td>Col 3 is</td>
161+
<td align="center">Right-Aligned</td>
162+
<td align="right">$20</td>
163+
</tr>
164+
</tbody>
165+
</table>
166+
TABLE, false);
167+
}
168+
119169
public static function markdownEncodedTemplateDataProvider()
120170
{
121171
yield ['[Laravel](https://laravel.com)', '<em>Hi</em> [Laravel](https://laravel.com)'];

tests/Integration/Mail/MailableWithoutSecuredEncodingTest.php

+50
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,56 @@ public function build()
116116
$mailable->assertSeeInHtml($expected, false);
117117
}
118118

119+
#[WithMigration]
120+
#[DataProvider('markdownEncodedTemplateDataProvider')]
121+
public function testItCanAssertMarkdownEncodedStringUsingTemplateWithTable($given, $expected)
122+
{
123+
$user = UserFactory::new()->create([
124+
'name' => $given,
125+
]);
126+
127+
$mailable = new class($user) extends Mailable
128+
{
129+
public $theme = 'taylor';
130+
131+
public function __construct(public User $user)
132+
{
133+
//
134+
}
135+
136+
public function build()
137+
{
138+
return $this->markdown('table-with-template');
139+
}
140+
};
141+
142+
$mailable->assertSeeInHtml($expected, false);
143+
$mailable->assertSeeInHtml('<p>This is a subcopy</p>', false);
144+
$mailable->assertSeeInHtml(<<<'TABLE'
145+
<table>
146+
<thead>
147+
<tr>
148+
<th>Laravel</th>
149+
<th align="center">Table</th>
150+
<th align="right">Example</th>
151+
</tr>
152+
</thead>
153+
<tbody>
154+
<tr>
155+
<td>Col 2 is</td>
156+
<td align="center">Centered</td>
157+
<td align="right">$10</td>
158+
</tr>
159+
<tr>
160+
<td>Col 3 is</td>
161+
<td align="center">Right-Aligned</td>
162+
<td align="right">$20</td>
163+
</tr>
164+
</tbody>
165+
</table>
166+
TABLE, false);
167+
}
168+
119169
public static function markdownEncodedTemplateDataProvider()
120170
{
121171
yield ['[Laravel](https://laravel.com)', '<p><em>Hi</em> <a href="https://laravel.com">Laravel</a></p>'];

tests/Integration/Mail/MarkdownParserTest.php

+5
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ public static function markdownEncodedDataProvider()
7676
'<p>Visit &lt;span&gt;https://laravel.com/docs&lt;/span&gt; to browse the documentation</p>',
7777
];
7878

79+
yield [
80+
new EncodedHtmlString(new HtmlString('Visit <span>https://laravel.com/docs</span> to browse the documentation')),
81+
'<p>Visit <span>https://laravel.com/docs</span> to browse the documentation</p>',
82+
];
83+
7984
yield [
8085
'![Welcome to Laravel](https://laravel.com/assets/img/welcome/background.svg)<br />'.new EncodedHtmlString('Visit <span>https://laravel.com/docs</span> to browse the documentation'),
8186
'<p><img src="https://laravel.com/assets/img/welcome/background.svg" alt="Welcome to Laravel" /><br />Visit &lt;span&gt;https://laravel.com/docs&lt;/span&gt; to browse the documentation</p>',

0 commit comments

Comments
 (0)