33namespace  Illuminate \Mail ;
44
55use  Illuminate \Contracts \View \Factory  as  ViewFactory ;
6+ use  Illuminate \Support \EncodedHtmlString ;
67use  Illuminate \Support \HtmlString ;
78use  Illuminate \Support \Str ;
89use  League \CommonMark \Environment \Environment ;
@@ -34,6 +35,13 @@ class Markdown
3435     */ 
3536    protected  $ componentPaths
3637
38+     /** 
39+      * Indicates if secure encoding should be enabled. 
40+      * 
41+      * @var bool 
42+      */ 
43+     protected  static  $ withSecuredEncodingfalse ;
44+ 
3745    /** 
3846     * Create a new Markdown renderer instance. 
3947     * 
@@ -59,9 +67,37 @@ public function render($view, array $data = [], $inliner = null)
5967    {
6068        $ this view ->flushFinderCache ();
6169
62-         $ contents$ this view ->replaceNamespace (
63-             'mail ' , $ this htmlComponentPaths ()
64-         )->make ($ view$ datarender ();
70+         $ bladeCompiler$ this view 
71+             ->getEngineResolver ()
72+             ->resolve ('blade ' )
73+             ->getCompiler ();
74+ 
75+         $ contents$ bladeCompilerusingEchoFormat (
76+             'new \Illuminate\Support\EncodedHtmlString(%s) ' ,
77+             function  () use  ($ view$ data
78+                 if  (static ::$ withSecuredEncodingtrue ) {
79+                     EncodedHtmlString::encodeUsing (function  ($ value
80+                         $ replacements
81+                             '[ '  => '\[ ' ,
82+                             '< '  => '< ' ,
83+                             '> '  => '> ' ,
84+                         ];
85+ 
86+                         return  str_replace (array_keys ($ replacementsarray_values ($ replacements$ value
87+                     });
88+                 }
89+ 
90+                 try  {
91+                     $ contents$ this view ->replaceNamespace (
92+                         'mail ' , $ this htmlComponentPaths ()
93+                     )->make ($ view$ datarender ();
94+                 } finally  {
95+                     EncodedHtmlString::flushState ();
96+                 }
97+ 
98+                 return  $ contents
99+             }
100+         );
65101
66102        if  ($ this view ->exists ($ customThemestart ($ this theme , 'mail. ' ))) {
67103            $ theme$ customTheme
@@ -72,7 +108,7 @@ public function render($view, array $data = [], $inliner = null)
72108        }
73109
74110        return  new  HtmlString (($ inlinernew  CssToInlineStyles )->convert (
75-             $ contents$ this view ->make ($ theme$ datarender ()
111+             str_replace ( ' \[ ' ,  ' [ ' ,  $ contents) , $ this view ->make ($ theme$ datarender ()
76112        ));
77113    }
78114
@@ -100,20 +136,59 @@ public function renderText($view, array $data = [])
100136     * Parse the given Markdown text into HTML. 
101137     * 
102138     * @param  string  $text 
139+      * @param  bool  $encoded 
103140     * @return \Illuminate\Support\HtmlString 
104141     */ 
105-     public  static  function  parse ($ text
142+     public  static  function  parse ($ text,  bool   $ encoded  =  false )
106143    {
107-         $ environmentnew  Environment ([
144+         if  ($ encodedfalse ) {
145+             return  new  HtmlString (static ::converter ()->convert ($ textgetContent ());
146+         }
147+ 
148+         if  (static ::$ withSecuredEncodingtrue  || $ encodedtrue ) {
149+             EncodedHtmlString::encodeUsing (function  ($ value
150+                 $ replacements
151+                     '[ '  => '\[ ' ,
152+                     '< '  => '\< ' ,
153+                 ];
154+ 
155+                 $ htmlstr_replace (array_keys ($ replacementsarray_values ($ replacements$ value
156+ 
157+                 return  static ::converter ([
158+                     'html_input '  => 'escape ' ,
159+                 ])->convert ($ htmlgetContent ();
160+             });
161+         }
162+ 
163+         $ html'' ;
164+ 
165+         try  {
166+             $ htmlstatic ::converter ()->convert ($ textgetContent ();
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+         $ environmentnew  Environment (array_merge ([
108185            'allow_unsafe_links '  => false ,
109-         ]);
186+         ],  $ config ) );
110187
111188        $ environmentaddExtension (new  CommonMarkCoreExtension );
112189        $ environmentaddExtension (new  TableExtension );
113190
114-         $ converternew  MarkdownConverter ($ environment
115- 
116-         return  new  HtmlString ($ converterconvert ($ textgetContent ());
191+         return  new  MarkdownConverter ($ environment
117192    }
118193
119194    /** 
@@ -185,4 +260,34 @@ public function getTheme()
185260    {
186261        return  $ this theme ;
187262    }
263+ 
264+     /** 
265+      * Enable secured encoding when parsing Markdown. 
266+      * 
267+      * @return void 
268+      */ 
269+     public  static  function  withSecuredEncoding ()
270+     {
271+         static ::$ withSecuredEncodingtrue ;
272+     }
273+ 
274+     /** 
275+      * Disable secured encoding when parsing Markdown. 
276+      * 
277+      * @return void 
278+      */ 
279+     public  static  function  withoutSecuredEncoding ()
280+     {
281+         static ::$ withSecuredEncodingfalse ;
282+     }
283+ 
284+     /** 
285+      * Flush the class's global state. 
286+      * 
287+      * @return void 
288+      */ 
289+     public  static  function  flushState ()
290+     {
291+         static ::$ withSecuredEncodingfalse ;
292+     }
188293}
0 commit comments