@@ -278,6 +278,8 @@ fn email_match<'a>(
278278
279279 let size = contents. len ( ) ;
280280
281+ let mut auto_mailto = true ;
282+ let mut is_xmpp = false ;
281283 let mut rewind = 0 ;
282284
283285 while rewind < i {
@@ -288,6 +290,21 @@ fn email_match<'a>(
288290 continue ;
289291 }
290292
293+ if c == b':' {
294+ if validate_protocol ( "mailto" . to_string ( ) , contents, i - rewind - 1 ) {
295+ auto_mailto = false ;
296+ rewind += 1 ;
297+ continue ;
298+ }
299+
300+ if validate_protocol ( "xmpp" . to_string ( ) , contents, i - rewind - 1 ) {
301+ is_xmpp = true ;
302+ auto_mailto = false ;
303+ rewind += 1 ;
304+ continue ;
305+ }
306+ }
307+
291308 break ;
292309 }
293310
@@ -307,6 +324,8 @@ fn email_match<'a>(
307324 return None ;
308325 } else if c == b'.' && link_end < size - i - 1 && isalnum ( contents[ i + link_end + 1 ] ) {
309326 np += 1 ;
327+ } else if c == b'/' && is_xmpp {
328+ // xmpp allows a `/` in the url
310329 } else if c != b'-' && c != b'_' {
311330 break ;
312331 }
@@ -326,7 +345,11 @@ fn email_match<'a>(
326345 return None ;
327346 }
328347
329- let mut url = "mailto:" . to_string ( ) ;
348+ let mut url = if auto_mailto {
349+ "mailto:" . to_string ( )
350+ } else {
351+ "" . to_string ( )
352+ } ;
330353 let text = str:: from_utf8 ( & contents[ i - rewind..link_end + i] ) . unwrap ( ) ;
331354 url. push_str ( text) ;
332355
@@ -346,3 +369,15 @@ fn email_match<'a>(
346369 ) ) ;
347370 Some ( ( inl, rewind, rewind + link_end) )
348371}
372+
373+ fn validate_protocol ( protocol : String , contents : & [ u8 ] , cursor : usize ) -> bool {
374+ let size = contents. len ( ) ;
375+ let mut rewind = 0 ;
376+
377+ while rewind < cursor && isalpha ( contents[ cursor - rewind - 1 ] ) {
378+ rewind += 1 ;
379+ }
380+
381+ size - cursor + rewind >= protocol. len ( )
382+ && & contents[ cursor - rewind..cursor] == protocol. as_bytes ( )
383+ }
0 commit comments