Refine BBCode::expandTags regular expression

- Now requires the tag to be preceded by either a non-word character or a start of a line
- Added corresponding tests
This commit is contained in:
Hypolite Petovan 2021-09-12 00:06:14 -04:00
parent 5a93bb6eff
commit 8e99b7f775
2 changed files with 31 additions and 2 deletions

View File

@ -2289,14 +2289,14 @@ class BBCode
} }
/** /**
* Expand tags to URLs * Expand tags to URLs, checks the tag is at the start of a line or preceded by a non-word character
* *
* @param string $body * @param string $body
* @return string body with expanded tags * @return string body with expanded tags
*/ */
public static function expandTags(string $body) public static function expandTags(string $body)
{ {
return preg_replace_callback("/([!#@])([^\^ \x0D\x0A,;:?\']*[^\^ \x0D\x0A,;:?!\'.])/", return preg_replace_callback("/(?<=\W|^)([!#@])([^\^ \x0D\x0A,;:?'\"]*[^\^ \x0D\x0A,;:?!'\".])/",
function ($match) { function ($match) {
switch ($match[1]) { switch ($match[1]) {
case '!': case '!':
@ -2309,6 +2309,7 @@ class BBCode
} }
break; break;
case '#': case '#':
default:
return $match[1] . '[url=' . 'https://' . DI::baseUrl() . '/search?tag=' . $match[2] . ']' . $match[2] . '[/url]'; return $match[1] . '[url=' . 'https://' . DI::baseUrl() . '/search?tag=' . $match[2] . ']' . $match[2] . '[/url]';
} }
}, $body); }, $body);

View File

@ -75,6 +75,7 @@ class BBCodeTest extends MockedTest
->andReturn($baseUrlMock); ->andReturn($baseUrlMock);
$baseUrlMock->shouldReceive('getHostname')->withNoArgs()->andReturn('friendica.local'); $baseUrlMock->shouldReceive('getHostname')->withNoArgs()->andReturn('friendica.local');
$baseUrlMock->shouldReceive('getUrlPath')->withNoArgs()->andReturn(''); $baseUrlMock->shouldReceive('getUrlPath')->withNoArgs()->andReturn('');
$baseUrlMock->shouldReceive('__toString')->withNoArgs()->andReturn('friendica.local');
$config = \HTMLPurifier_HTML5Config::createDefault(); $config = \HTMLPurifier_HTML5Config::createDefault();
$config->set('HTML.Doctype', 'HTML5'); $config->set('HTML.Doctype', 'HTML5');
@ -339,4 +340,31 @@ class BBCodeTest extends MockedTest
self::assertEquals($expected, $actual); self::assertEquals($expected, $actual);
} }
public function dataExpandTags()
{
return [
'bug-10692-non-word' => [
'[url=https://github.com/friendica/friendica/blob/2021.09-rc/src/Util/Logger/StreamLogger.php#L160]https://github.com/friendica/friendica/blob/2021.09-rc/src/Util/Logger/StreamLogger.php#L160[/url]',
'[url=https://github.com/friendica/friendica/blob/2021.09-rc/src/Util/Logger/StreamLogger.php#L160]https://github.com/friendica/friendica/blob/2021.09-rc/src/Util/Logger/StreamLogger.php#L160[/url]',
],
'bug-10692-start-line' => [
'#[url=https://friendica.local/search?tag=L160]L160[/url]',
'#L160',
]
];
}
/**
* @dataProvider dataExpandTags
*
* @param string $expected Expected BBCode output
* @param string $text Input text
*/
public function testExpandTags(string $expected, string $text)
{
$actual = BBCode::expandTags($text);
self::assertEquals($expected, $actual);
}
} }