Add tag escaping to Item::setHashtags
- Add return value to Item::setHashtags
This commit is contained in:
parent
472018191b
commit
76460ddd2d
|
@ -642,7 +642,7 @@ function item_post(App $a) {
|
||||||
|
|
||||||
// Check for hashtags in the body and repair or add hashtag links
|
// Check for hashtags in the body and repair or add hashtag links
|
||||||
if ($preview || $orig_post) {
|
if ($preview || $orig_post) {
|
||||||
Item::setHashtags($datarray);
|
$datarray['body'] = Item::setHashtags($datarray['body']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// preview mode - prepare the body for display and send it via json
|
// preview mode - prepare the body for display and send it via json
|
||||||
|
|
|
@ -1780,7 +1780,7 @@ class Item
|
||||||
|
|
||||||
|
|
||||||
// Check for hashtags in the body and repair or add hashtag links
|
// Check for hashtags in the body and repair or add hashtag links
|
||||||
self::setHashtags($item);
|
$item['body'] = self::setHashtags($item['body']);
|
||||||
|
|
||||||
// Fill the cache field
|
// Fill the cache field
|
||||||
self::putInCache($item);
|
self::putInCache($item);
|
||||||
|
@ -2424,84 +2424,69 @@ class Item
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function setHashtags(&$item)
|
public static function setHashtags($body)
|
||||||
{
|
{
|
||||||
$tags = BBCode::getTags($item["body"]);
|
$body = BBCode::performWithEscapedTags($body, ['noparse', 'pre', 'code'], function ($body) {
|
||||||
|
$tags = BBCode::getTags($body);
|
||||||
|
|
||||||
// No hashtags?
|
// No hashtags?
|
||||||
if (!count($tags)) {
|
if (!count($tags)) {
|
||||||
return false;
|
return $body;
|
||||||
}
|
|
||||||
|
|
||||||
// What happens in [code], stays in [code]!
|
|
||||||
// escape the # and the [
|
|
||||||
// hint: we will also get in trouble with #tags, when we want markdown in posts -> ### Headline 3
|
|
||||||
$item["body"] = preg_replace_callback("/\[code(.*?)\](.*?)\[\/code\]/ism",
|
|
||||||
function ($match) {
|
|
||||||
// we truly ESCape all # and [ to prevent gettin weird tags in [code] blocks
|
|
||||||
$find = ['#', '['];
|
|
||||||
$replace = [chr(27).'sharp', chr(27).'leftsquarebracket'];
|
|
||||||
return ("[code" . $match[1] . "]" . str_replace($find, $replace, $match[2]) . "[/code]");
|
|
||||||
}, $item["body"]);
|
|
||||||
|
|
||||||
// This sorting is important when there are hashtags that are part of other hashtags
|
|
||||||
// Otherwise there could be problems with hashtags like #test and #test2
|
|
||||||
// Because of this we are sorting from the longest to the shortest tag.
|
|
||||||
usort($tags, function($a, $b) {
|
|
||||||
return strlen($b) <=> strlen($a);
|
|
||||||
});
|
|
||||||
|
|
||||||
$URLSearchString = "^\[\]";
|
|
||||||
|
|
||||||
// All hashtags should point to the home server if "local_tags" is activated
|
|
||||||
if (DI::config()->get('system', 'local_tags')) {
|
|
||||||
$item["body"] = preg_replace("/#\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",
|
|
||||||
"#[url=".DI::baseUrl()."/search?tag=$2]$2[/url]", $item["body"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// mask hashtags inside of url, bookmarks and attachments to avoid urls in urls
|
|
||||||
$item["body"] = preg_replace_callback("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",
|
|
||||||
function ($match) {
|
|
||||||
return ("[url=" . str_replace("#", "#", $match[1]) . "]" . str_replace("#", "#", $match[2]) . "[/url]");
|
|
||||||
}, $item["body"]);
|
|
||||||
|
|
||||||
$item["body"] = preg_replace_callback("/\[bookmark\=([$URLSearchString]*)\](.*?)\[\/bookmark\]/ism",
|
|
||||||
function ($match) {
|
|
||||||
return ("[bookmark=" . str_replace("#", "#", $match[1]) . "]" . str_replace("#", "#", $match[2]) . "[/bookmark]");
|
|
||||||
}, $item["body"]);
|
|
||||||
|
|
||||||
$item["body"] = preg_replace_callback("/\[attachment (.*)\](.*?)\[\/attachment\]/ism",
|
|
||||||
function ($match) {
|
|
||||||
return ("[attachment " . str_replace("#", "#", $match[1]) . "]" . $match[2] . "[/attachment]");
|
|
||||||
}, $item["body"]);
|
|
||||||
|
|
||||||
// Repair recursive urls
|
|
||||||
$item["body"] = preg_replace("/#\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",
|
|
||||||
"#$2", $item["body"]);
|
|
||||||
|
|
||||||
foreach ($tags as $tag) {
|
|
||||||
if ((strpos($tag, '#') !== 0) || strpos($tag, '[url=') || strlen($tag) < 2 || $tag[1] == '#') {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$basetag = str_replace('_',' ',substr($tag,1));
|
// This sorting is important when there are hashtags that are part of other hashtags
|
||||||
$newtag = '#[url=' . DI::baseUrl() . '/search?tag=' . $basetag . ']' . $basetag . '[/url]';
|
// Otherwise there could be problems with hashtags like #test and #test2
|
||||||
|
// Because of this we are sorting from the longest to the shortest tag.
|
||||||
|
usort($tags, function ($a, $b) {
|
||||||
|
return strlen($b) <=> strlen($a);
|
||||||
|
});
|
||||||
|
|
||||||
$item["body"] = str_replace($tag, $newtag, $item["body"]);
|
$URLSearchString = "^\[\]";
|
||||||
}
|
|
||||||
|
|
||||||
// Convert back the masked hashtags
|
// All hashtags should point to the home server if "local_tags" is activated
|
||||||
$item["body"] = str_replace("#", "#", $item["body"]);
|
if (DI::config()->get('system', 'local_tags')) {
|
||||||
|
$body = preg_replace("/#\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",
|
||||||
|
"#[url=" . DI::baseUrl() . "/search?tag=$2]$2[/url]", $body);
|
||||||
|
}
|
||||||
|
|
||||||
// Remember! What happens in [code], stays in [code]
|
// mask hashtags inside of url, bookmarks and attachments to avoid urls in urls
|
||||||
// roleback the # and [
|
$body = preg_replace_callback("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",
|
||||||
$item["body"] = preg_replace_callback("/\[code(.*?)\](.*?)\[\/code\]/ism",
|
function ($match) {
|
||||||
function ($match) {
|
return ("[url=" . str_replace("#", "#", $match[1]) . "]" . str_replace("#", "#", $match[2]) . "[/url]");
|
||||||
// we truly unESCape all sharp and leftsquarebracket
|
}, $body);
|
||||||
$find = [chr(27).'sharp', chr(27).'leftsquarebracket'];
|
|
||||||
$replace = ['#', '['];
|
$body = preg_replace_callback("/\[bookmark\=([$URLSearchString]*)\](.*?)\[\/bookmark\]/ism",
|
||||||
return ("[code" . $match[1] . "]" . str_replace($find, $replace, $match[2]) . "[/code]");
|
function ($match) {
|
||||||
}, $item["body"]);
|
return ("[bookmark=" . str_replace("#", "#", $match[1]) . "]" . str_replace("#", "#", $match[2]) . "[/bookmark]");
|
||||||
|
}, $body);
|
||||||
|
|
||||||
|
$body = preg_replace_callback("/\[attachment (.*)\](.*?)\[\/attachment\]/ism",
|
||||||
|
function ($match) {
|
||||||
|
return ("[attachment " . str_replace("#", "#", $match[1]) . "]" . $match[2] . "[/attachment]");
|
||||||
|
}, $body);
|
||||||
|
|
||||||
|
// Repair recursive urls
|
||||||
|
$body = preg_replace("/#\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",
|
||||||
|
"#$2", $body);
|
||||||
|
|
||||||
|
foreach ($tags as $tag) {
|
||||||
|
if ((strpos($tag, '#') !== 0) || strpos($tag, '[url=') || strlen($tag) < 2 || $tag[1] == '#') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$basetag = str_replace('_', ' ', substr($tag, 1));
|
||||||
|
$newtag = '#[url=' . DI::baseUrl() . '/search?tag=' . $basetag . ']' . $basetag . '[/url]';
|
||||||
|
|
||||||
|
$body = str_replace($tag, $newtag, $body);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert back the masked hashtags
|
||||||
|
$body = str_replace("#", "#", $body);
|
||||||
|
|
||||||
|
return $body;
|
||||||
|
});
|
||||||
|
|
||||||
|
return $body;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -102,14 +102,12 @@ class Babel extends BaseModule
|
||||||
'content' => visible_whitespace($bbcode4)
|
'content' => visible_whitespace($bbcode4)
|
||||||
];
|
];
|
||||||
|
|
||||||
$item = ['body' => $bbcode];
|
|
||||||
|
|
||||||
$tags = Text\BBCode::getTags($bbcode);
|
$tags = Text\BBCode::getTags($bbcode);
|
||||||
|
|
||||||
Item::setHashtags($item);
|
$body = Item::setHashtags($bbcode);
|
||||||
$results[] = [
|
$results[] = [
|
||||||
'title' => DI::l10n()->t('Item Body'),
|
'title' => DI::l10n()->t('Item Body'),
|
||||||
'content' => visible_whitespace($item['body'])
|
'content' => visible_whitespace($body)
|
||||||
];
|
];
|
||||||
$results[] = [
|
$results[] = [
|
||||||
'title' => DI::l10n()->t('Item Tags'),
|
'title' => DI::l10n()->t('Item Tags'),
|
||||||
|
@ -125,9 +123,7 @@ class Babel extends BaseModule
|
||||||
|
|
||||||
$markdown = XML::unescape($diaspora);
|
$markdown = XML::unescape($diaspora);
|
||||||
case 'markdown':
|
case 'markdown':
|
||||||
if (!isset($markdown)) {
|
$markdown = $markdown ?? trim($_REQUEST['text']);
|
||||||
$markdown = trim($_REQUEST['text']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$results[] = [
|
$results[] = [
|
||||||
'title' => DI::l10n()->t('Source input (Markdown)'),
|
'title' => DI::l10n()->t('Source input (Markdown)'),
|
||||||
|
|
Loading…
Reference in a new issue