}
/**
- * 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
* @return string body with expanded tags
*/
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) {
switch ($match[1]) {
case '!':
}
break;
case '#':
+ default:
return $match[1] . '[url=' . 'https://' . DI::baseUrl() . '/search?tag=' . $match[2] . ']' . $match[2] . '[/url]';
}
}, $body);
->andReturn($baseUrlMock);
$baseUrlMock->shouldReceive('getHostname')->withNoArgs()->andReturn('friendica.local');
$baseUrlMock->shouldReceive('getUrlPath')->withNoArgs()->andReturn('');
+ $baseUrlMock->shouldReceive('__toString')->withNoArgs()->andReturn('friendica.local');
$config = \HTMLPurifier_HTML5Config::createDefault();
$config->set('HTML.Doctype', 'HTML5');
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);
+ }
}