@@ -149,10 +149,29 @@ public function escapeHtmlWithLinks($data, $allowedTags = null)
149
149
$ links = [];
150
150
$ i = 1 ;
151
151
$ data = str_replace ('% ' , '%% ' , $ data );
152
- $ regexp = ' @(<a [^>]*>(?:[^<]|<[^/]|</[^a]|</a[^>])*< /a>)@ ' ;
152
+ $ regexp = " /<a\s [^>]*href\s*?=\s*?([ \" \']??)([^ \" >]*?) \\ 1[^>]*>(.*)<\ /a>/siU " ;
153
153
while (preg_match ($ regexp , $ data , $ matches )) {
154
- $ links [] = $ matches [1 ];
155
- $ data = str_replace ($ matches [1 ], '% ' . $ i . '$s ' , $ data );
154
+ //Revert the sprintf escaping
155
+ $ url = str_replace ('%% ' , '% ' , $ matches [2 ]);
156
+ $ text = str_replace ('%% ' , '% ' , $ matches [3 ]);
157
+ //Check for an valid url
158
+ if ($ url ) {
159
+ $ urlScheme = strtolower (parse_url ($ url , PHP_URL_SCHEME ));
160
+ if ($ urlScheme !== 'http ' && $ urlScheme !== 'https ' ) {
161
+ $ url = null ;
162
+ }
163
+ }
164
+ //Use hash tag as fallback
165
+ if (!$ url ) {
166
+ $ url = '# ' ;
167
+ }
168
+ //Recreate a minimalistic secure a tag
169
+ $ links [] = sprintf (
170
+ '<a href="%s">%s</a> ' ,
171
+ htmlspecialchars ($ url , ENT_QUOTES , 'UTF-8 ' , false ),
172
+ $ this ->escaper ->escapeHtml ($ text )
173
+ );
174
+ $ data = str_replace ($ matches [0 ], '% ' . $ i . '$s ' , $ data );
156
175
++$ i ;
157
176
}
158
177
$ data = $ this ->escaper ->escapeHtml ($ data , $ allowedTags );
0 commit comments