@@ -59,6 +59,8 @@ class Autolink
5959 */
6060 protected $ linkBuilder ;
6161
62+ protected ?\Closure $ escapeHandler = null ;
63+
6264 /**
6365 * Class init.
6466 *
@@ -137,7 +139,7 @@ function ($matches) use ($attribs) {
137139 preg_match ('/[a-zA-Z]*\=\"(.*)/ ' , $ matches [0 ], $ inElements );
138140
139141 if (!$ inElements ) {
140- $ email = $ this ->isAutoEscape () ? htmlspecialchars ($ matches [0 ]) : $ matches [0 ];
142+ $ email = $ this ->isAutoEscape () ? $ this -> escape ($ matches [0 ]) : $ matches [0 ];
141143
142144 $ attribs ['href ' ] = 'mailto: ' . $ email ;
143145
@@ -176,7 +178,7 @@ public function link(string $url, array $attribs = []): string
176178 }
177179 }
178180
179- $ attribs ['href ' ] = $ this ->isAutoEscape () ? htmlspecialchars ($ url ) : $ url ;
181+ $ attribs ['href ' ] = $ this ->isAutoEscape () ? $ this -> escape ($ url ) : $ url ;
180182
181183 if (($ scheme = $ this ->getLinkNoScheme ()) && !str_contains ($ attribs ['href ' ], ':// ' )) {
182184 $ scheme = is_string ($ scheme ) ? $ scheme : 'http ' ;
@@ -185,11 +187,7 @@ public function link(string $url, array $attribs = []): string
185187 }
186188
187189 if ($ this ->isAutoTitle ()) {
188- $ attribs ['title ' ] = htmlspecialchars (
189- $ url ,
190- // PHP 8.1 or higher will escape single quote
191- ENT_QUOTES | ENT_SUBSTITUTE
192- );
190+ $ attribs ['title ' ] = $ this ->escape ($ url );
193191 }
194192
195193 return $ this ->buildLink ($ content , $ attribs );
@@ -209,7 +207,7 @@ protected function buildLink(?string $url = null, array $attribs = []): string
209207 return (string ) ($ this ->linkBuilder )($ url , $ attribs );
210208 }
211209
212- return HtmlBuilder::create ('a ' , $ attribs , htmlspecialchars ($ url ));
210+ return HtmlBuilder::create ('a ' , $ attribs , $ this -> escape ($ url ));
213211 }
214212
215213 /**
@@ -486,4 +484,23 @@ public static function shortenUrl(string $url, int $lastPartLimit = 15, int $dot
486484
487485 return $ first . str_repeat ('. ' , $ dots ) . $ last ;
488486 }
487+
488+ public function escape (string $ str ): string
489+ {
490+ return $ this ->getEscapeHandler ()($ str );
491+ }
492+
493+ public function getEscapeHandler (): ?\Closure
494+ {
495+ return $ this ->escapeHandler
496+ // PHP 8.1 or higher will escape single quite
497+ ?? static fn ($ str ) => htmlspecialchars ($ str , ENT_QUOTES | ENT_SUBSTITUTE );
498+ }
499+
500+ public function setEscapeHandler (?\Closure $ escapeHandler ): static
501+ {
502+ $ this ->escapeHandler = $ escapeHandler ;
503+
504+ return $ this ;
505+ }
489506}
0 commit comments