diff --git a/lib/util.php b/lib/util.php
index 2be4213e79..ee3fe5ddcf 100644
--- a/lib/util.php
+++ b/lib/util.php
@@ -412,30 +412,34 @@ function common_render_text($text)
function common_replace_urls_callback($text, $callback, $notice_id = null) {
// Start off with a regex
$regex = '#'.
- '(?:^|[\s\(\)\[\]\{\}]+)'.
- '('.
+ '(?:^|[\s\(\)\[\]\{\}\\\'\\\";]+)(?![\@\!\#])'.
+ '('.
'(?:'.
'(?:'. //Known protocols
'(?:'.
'(?:https?|ftps?|mms|rtsp|gopher|news|nntp|telnet|wais|file|prospero|webcal|irc)://'.
'|'.
'(?:mailto|aim|tel|xmpp):'.
- ')[^\s\/]+'.
+ ')'.
+ '(?:[\pN\pL\-\_\+]+(?:\:[\pN\pL\-\_\+]+)?\@)?'. //user:pass@
+ '[\pN\pL\-\_\:\.]+(?127.0.0.1'),
+ array('127.0.0.1/test.php',
+ '127.0.0.1/test.php'),
+ array('http://::1/test.php',
+ 'http://::1/test.php'),
+ array('http://::1',
+ 'http://::1'),
+ array('2001:4978:1b5:0:21d:e0ff:fe66:59ab/test.php',
+ '2001:4978:1b5:0:21d:e0ff:fe66:59ab/test.php'),
+ array('2001:4978:1b5:0:21d:e0ff:fe66:59ab',
+ '2001:4978:1b5:0:21d:e0ff:fe66:59ab'),
+ array('http://127.0.0.1',
+ 'http://127.0.0.1'),
+ array('example.com',
+ 'example.com'),
+ array('example.com',
+ 'example.com'),
+ array('http://example.com',
+ 'http://example.com'),
+ array('http://example.com.',
+ 'http://example.com.'),
+ array('/var/lib/example.so',
+ '/var/lib/example.so'),
array('example',
'example'),
+ array('user@example.com',
+ 'user@example.com'),
+ array('user_name+other@example.com',
+ 'user_name+other@example.com'),
+ array('mailto:user@example.com',
+ 'mailto:user@example.com'),
+ array('mailto:user@example.com?subject=test',
+ 'mailto:user@example.com?subject=test'),
+ array('#example',
+ '#example'),
+ array('#example.com',
+ '#example.com'),
+ array('#.net',
+ '#.net'),
array('http://example',
'http://example'),
+ array('http://3xampl3',
+ 'http://3xampl3'),
array('http://example/',
'http://example/'),
array('http://example/path',
@@ -47,6 +87,10 @@ class URLDetectionTest extends PHPUnit_Framework_TestCase
'http://user:pass@example.com'),
array('http://example.com:8080',
'http://example.com:8080'),
+ array('http://example.com:8080/test.php',
+ 'http://example.com:8080/test.php'),
+ array('example.com:8080/test.php',
+ 'example.com:8080/test.php'),
array('http://www.example.com',
'http://www.example.com'),
array('http://example.com/',
@@ -59,60 +103,65 @@ class URLDetectionTest extends PHPUnit_Framework_TestCase
'http://example.com/path.html#fragment'),
array('http://example.com/path.php?foo=bar&bar=foo',
'http://example.com/path.php?foo=bar&bar=foo'),
- array('http://müllärör.de',
- 'http://müllärör.de'),
- array('http://ﺱﺲﺷ.com',
- 'http://ﺱﺲﺷ.com'),
- array('http://сделаткартинки.com',
- 'http://сделаткартинки.com'),
- array('http://tūdaliņ.lv',
- 'http://tūdaliņ.lv'),
- array('http://brændendekærlighed.com',
- 'http://brændendekærlighed.com'),
- array('http://あーるいん.com',
- 'http://あーるいん.com'),
- array('http://예비교사.com',
- 'http://예비교사.com'),
array('http://example.com.',
- 'http://example.com.'),
+ 'http://example.com.'),
+ array('http://müllärör.de',
+ 'http://müllärör.de'),
+ array('http://ﺱﺲﺷ.com',
+ 'http://ﺱﺲﺷ.com'),
+ array('http://сделаткартинки.com',
+ 'http://сделаткартинки.com'),
+ array('http://tūdaliņ.lv',
+ 'http://tūdaliņ.lv'),
+ array('http://brændendekærlighed.com',
+ 'http://brændendekærlighed.com'),
+ array('http://あーるいん.com',
+ 'http://あーるいん.com'),
+ array('http://예비교사.com',
+ 'http://예비교사.com'),
+ array('http://example.com.',
+ 'http://example.com.'),
array('http://example.com?',
- 'http://example.com?'),
+ 'http://example.com?'),
array('http://example.com!',
- 'http://example.com!'),
+ 'http://example.com!'),
array('http://example.com,',
- 'http://example.com,'),
+ 'http://example.com,'),
array('http://example.com;',
- 'http://example.com;'),
+ 'http://example.com;'),
array('http://example.com:',
- 'http://example.com:'),
+ 'http://example.com:'),
array('\'http://example.com\'',
- '\'http://example.com\''),
+ '\'http://example.com\''),
array('"http://example.com"',
- '"http://example.com"'),
- array('http://example.com
',
- 'http://example.com'),
+ '"http://example.com"'),
+ array('http://example.com',
+ 'http://example.com'),
array('(http://example.com)',
- '(http://example.com)'),
+ '(http://example.com)'),
array('[http://example.com]',
- '[http://example.com]'),
+ '[http://example.com]'),
array('',
- '<http://example.com>'),
+ '<http://example.com>'),
array('http://example.com/path/(foo)/bar',
'http://example.com/path/(foo)/bar'),
+ //Not a valid url - urls cannot contain unencoded square brackets
array('http://example.com/path/[foo]/bar',
'http://example.com/path/[foo]/bar'),
array('http://example.com/path/foo/(bar)',
'http://example.com/path/foo/(bar)'),
- array('http://example.com/path/foo/[bar]',
- 'http://example.com/path/foo/[bar]'),
+ //Not a valid url - urls cannot contain unencoded square brackets
+ //array('http://example.com/path/foo/[bar]',
+ // 'http://example.com/path/foo/[bar]'),
array('Hey, check out my cool site http://example.com okay?',
- 'Hey, check out my cool site http://example.com okay?'),
+ 'Hey, check out my cool site http://example.com okay?'),
array('What about parens (e.g. http://example.com/path/foo/(bar))?',
'What about parens (e.g. http://example.com/path/foo/(bar))?'),
array('What about parens (e.g. http://example.com/path/foo/(bar)?',
'What about parens (e.g. http://example.com/path/foo/(bar)?'),
array('What about parens (e.g. http://example.com/path/foo/(bar).)?',
'What about parens (e.g. http://example.com/path/foo/(bar).)?'),
+ //Not a valid url - urls cannot contain unencoded commas
array('What about parens (e.g. http://example.com/path/(foo,bar)?',
'What about parens (e.g. http://example.com/path/(foo,bar)?'),
array('Unbalanced too (e.g. http://example.com/path/((((foo)/bar)?',
@@ -124,51 +173,51 @@ class URLDetectionTest extends PHPUnit_Framework_TestCase
array('Unbalanced too (e.g. http://example.com/path/foo/(bar))))?',
'Unbalanced too (e.g. http://example.com/path/foo/(bar))))?'),
array('example.com',
- 'example.com'),
+ 'example.com'),
array('example.org',
- 'example.org'),
+ 'example.org'),
array('example.co.uk',
- 'example.co.uk'),
+ 'example.co.uk'),
array('www.example.co.uk',
- 'www.example.co.uk'),
+ 'www.example.co.uk'),
array('farm1.images.example.co.uk',
- 'farm1.images.example.co.uk'),
+ 'farm1.images.example.co.uk'),
array('example.museum',
- 'example.museum'),
+ 'example.museum'),
array('example.travel',
- 'example.travel'),
+ 'example.travel'),
array('example.com.',
- 'example.com.'),
+ 'example.com.'),
array('example.com?',
- 'example.com?'),
+ 'example.com?'),
array('example.com!',
- 'example.com!'),
+ 'example.com!'),
array('example.com,',
- 'example.com,'),
+ 'example.com,'),
array('example.com;',
- 'example.com;'),
+ 'example.com;'),
array('example.com:',
- 'example.com:'),
+ 'example.com:'),
array('\'example.com\'',
- '\'example.com\''),
+ '\'example.com\''),
array('"example.com"',
- '"example.com"'),
- array('example.com
',
- 'example.com'),
+ '"example.com"'),
+ array('example.com',
+ 'example.com'),
array('(example.com)',
- '(example.com)'),
+ '(example.com)'),
array('[example.com]',
- '[example.com]'),
+ '[example.com]'),
array('',
- '<example.com>'),
+ '<example.com>'),
array('Hey, check out my cool site example.com okay?',
- 'Hey, check out my cool site example.com okay?'),
+ 'Hey, check out my cool site example.com okay?'),
array('Hey, check out my cool site example.com.I made it.',
- 'Hey, check out my cool site example.com.I made it.'),
+ 'Hey, check out my cool site example.com.I made it.'),
array('Hey, check out my cool site example.com.Funny thing...',
- 'Hey, check out my cool site example.com.Funny thing...'),
+ 'Hey, check out my cool site example.com.Funny thing...'),
array('Hey, check out my cool site example.com.You will love it.',
- 'Hey, check out my cool site example.com.You will love it.'),
+ 'Hey, check out my cool site example.com.You will love it.'),
array('What about parens (e.g. example.com/path/foo/(bar))?',
'What about parens (e.g. example.com/path/foo/(bar))?'),
array('What about parens (e.g. example.com/path/foo/(bar)?',