3
3
namespace Illuminate \Mail ;
4
4
5
5
use Illuminate \Contracts \View \Factory as ViewFactory ;
6
+ use Illuminate \Support \EncodedHtmlString ;
6
7
use Illuminate \Support \HtmlString ;
7
8
use Illuminate \Support \Str ;
8
9
use League \CommonMark \Environment \Environment ;
@@ -34,6 +35,13 @@ class Markdown
34
35
*/
35
36
protected $ componentPaths = [];
36
37
38
+ /**
39
+ * Indicates if secure encoding should be enabled.
40
+ *
41
+ * @var bool
42
+ */
43
+ protected static $ withSecuredEncoding = false ;
44
+
37
45
/**
38
46
* Create a new Markdown renderer instance.
39
47
*
@@ -59,9 +67,37 @@ public function render($view, array $data = [], $inliner = null)
59
67
{
60
68
$ this ->view ->flushFinderCache ();
61
69
62
- $ contents = $ this ->view ->replaceNamespace (
63
- 'mail ' , $ this ->htmlComponentPaths ()
64
- )->make ($ view , $ data )->render ();
70
+ $ bladeCompiler = $ this ->view
71
+ ->getEngineResolver ()
72
+ ->resolve ('blade ' )
73
+ ->getCompiler ();
74
+
75
+ $ contents = $ bladeCompiler ->usingEchoFormat (
76
+ 'new \Illuminate\Support\EncodedHtmlString(%s) ' ,
77
+ function () use ($ view , $ data ) {
78
+ if (static ::$ withSecuredEncoding === true ) {
79
+ EncodedHtmlString::encodeUsing (function ($ value ) {
80
+ $ replacements = [
81
+ '[ ' => '\[ ' ,
82
+ '< ' => '< ' ,
83
+ '> ' => '> ' ,
84
+ ];
85
+
86
+ return str_replace (array_keys ($ replacements ), array_values ($ replacements ), $ value );
87
+ });
88
+ }
89
+
90
+ try {
91
+ $ contents = $ this ->view ->replaceNamespace (
92
+ 'mail ' , $ this ->htmlComponentPaths ()
93
+ )->make ($ view , $ data )->render ();
94
+ } finally {
95
+ EncodedHtmlString::flushState ();
96
+ }
97
+
98
+ return $ contents ;
99
+ }
100
+ );
65
101
66
102
if ($ this ->view ->exists ($ customTheme = Str::start ($ this ->theme , 'mail. ' ))) {
67
103
$ theme = $ customTheme ;
@@ -72,7 +108,7 @@ public function render($view, array $data = [], $inliner = null)
72
108
}
73
109
74
110
return new HtmlString (($ inliner ?: new CssToInlineStyles )->convert (
75
- $ contents , $ this ->view ->make ($ theme , $ data )->render ()
111
+ str_replace ( ' \[ ' , ' [ ' , $ contents) , $ this ->view ->make ($ theme , $ data )->render ()
76
112
));
77
113
}
78
114
@@ -100,20 +136,59 @@ public function renderText($view, array $data = [])
100
136
* Parse the given Markdown text into HTML.
101
137
*
102
138
* @param string $text
139
+ * @param bool $encoded
103
140
* @return \Illuminate\Support\HtmlString
104
141
*/
105
- public static function parse ($ text )
142
+ public static function parse ($ text, bool $ encoded = false )
106
143
{
107
- $ environment = new Environment ([
144
+ if ($ encoded === false ) {
145
+ return new HtmlString (static ::converter ()->convert ($ text )->getContent ());
146
+ }
147
+
148
+ if (static ::$ withSecuredEncoding === true || $ encoded === true ) {
149
+ EncodedHtmlString::encodeUsing (function ($ value ) {
150
+ $ replacements = [
151
+ '[ ' => '\[ ' ,
152
+ '< ' => '\< ' ,
153
+ ];
154
+
155
+ $ html = str_replace (array_keys ($ replacements ), array_values ($ replacements ), $ value );
156
+
157
+ return static ::converter ([
158
+ 'html_input ' => 'escape ' ,
159
+ ])->convert ($ html )->getContent ();
160
+ });
161
+ }
162
+
163
+ $ html = '' ;
164
+
165
+ try {
166
+ $ html = static ::converter ()->convert ($ text )->getContent ();
167
+ } finally {
168
+ EncodedHtmlString::flushState ();
169
+ }
170
+
171
+ return new HtmlString ($ html );
172
+ }
173
+
174
+ /**
175
+ * Get a Markdown converter instance.
176
+ *
177
+ * @internal
178
+ *
179
+ * @param array<string, mixed> $config
180
+ * @return \League\CommonMark\MarkdownConverter
181
+ */
182
+ public static function converter (array $ config = [])
183
+ {
184
+ $ environment = new Environment (array_merge ([
108
185
'allow_unsafe_links ' => false ,
109
- ]);
186
+ ], $ config ) );
110
187
111
188
$ environment ->addExtension (new CommonMarkCoreExtension );
112
189
$ environment ->addExtension (new TableExtension );
113
190
114
- $ converter = new MarkdownConverter ($ environment );
115
-
116
- return new HtmlString ($ converter ->convert ($ text )->getContent ());
191
+ return new MarkdownConverter ($ environment );
117
192
}
118
193
119
194
/**
@@ -185,4 +260,34 @@ public function getTheme()
185
260
{
186
261
return $ this ->theme ;
187
262
}
263
+
264
+ /**
265
+ * Enable secured encoding when parsing Markdown.
266
+ *
267
+ * @return void
268
+ */
269
+ public static function withSecuredEncoding ()
270
+ {
271
+ static ::$ withSecuredEncoding = true ;
272
+ }
273
+
274
+ /**
275
+ * Disable secured encoding when parsing Markdown.
276
+ *
277
+ * @return void
278
+ */
279
+ public static function withoutSecuredEncoding ()
280
+ {
281
+ static ::$ withSecuredEncoding = false ;
282
+ }
283
+
284
+ /**
285
+ * Flush the class's global state.
286
+ *
287
+ * @return void
288
+ */
289
+ public static function flushState ()
290
+ {
291
+ static ::$ withSecuredEncoding = false ;
292
+ }
188
293
}
0 commit comments