]> git.mxchange.org Git - friendica.git/blobdiff - src/Content/Text/BBCode.php
Merge pull request #8022 from nupplaphil/task/mod_hcard
[friendica.git] / src / Content / Text / BBCode.php
index 6da3e62faefe3896695f339b7a8b7661142fd8eb..3617470df4ff175cc0505cf1e5ea934427b6c0c6 100644 (file)
@@ -355,7 +355,7 @@ class BBCode extends BaseObject
                        }
 
                        // Simplify "video" element
-                       $post['text'] = preg_replace("(\[video.*?\s?src\s?=\s?([^\s\]]*).*?\].*?\[\/video\\])ism", "[video]$1[/video]", $post['text']);
+                       $post['text'] = preg_replace('(\[video.*?\ssrc\s?=\s?([^\s\]]+).*?\].*?\[/video\])ism', '[video]$1[/video]', $post['text']);
 
                        // Now count the number of external media links
                        preg_match_all("(\[vimeo\](.*?)\[\/vimeo\])ism", $post['text'], $links1, PREG_SET_ORDER);
@@ -398,15 +398,15 @@ class BBCode extends BaseObject
         */
        public static function removeAttachment($body, $no_link_desc = false)
        {
-               return preg_replace_callback("/\[attachment (.*)\](.*?)\[\/attachment\]/ism",
+               return preg_replace_callback("/\s*\[attachment (.*)\](.*?)\[\/attachment\]\s*/ism",
                        function ($match) use ($no_link_desc) {
                                $attach_data = self::getAttachmentData($match[0]);
                                if (empty($attach_data['url'])) {
                                        return $match[0];
                                } elseif (empty($attach_data['title']) || $no_link_desc) {
-                                       return '[url]' . $attach_data['url'] . "[/url]\n";
+                                       return "\n[url]" . $attach_data['url'] . "[/url]\n";
                                } else {
-                                       return '[url=' . $attach_data['url'] . ']' . $attach_data['title'] . "[/url]\n";
+                                       return "\n[url=" . $attach_data['url'] . ']' . $attach_data['title'] . "[/url]\n";
                                }
                }, $body);
        }
@@ -1283,9 +1283,9 @@ class BBCode extends BaseObject
                        function ($matches) use (&$codeblocks) {
                                $return = '#codeblock-' . count($codeblocks) . '#';
                                if (strpos($matches[2], "\n") !== false) {
-                                       $codeblocks[] = '<pre><code class="language-' . trim($matches[1]) . '">' . trim($matches[2], "\n\r") . '</code></pre>';
+                                       $codeblocks[] = '<pre><code class="language-' . trim($matches[1]) . '">' . htmlspecialchars(trim($matches[2], "\n\r"), ENT_NOQUOTES, 'UTF-8') . '</code></pre>';
                                } else {
-                                       $codeblocks[] = '<code>' . $matches[2] . '</code>';
+                                       $codeblocks[] = '<code>' . htmlspecialchars($matches[2], ENT_NOQUOTES, 'UTF-8') . '</code>';
                                }
 
                                return $return;
@@ -1507,8 +1507,29 @@ class BBCode extends BaseObject
                $text = str_replace('[hr]', '<hr />', $text);
 
                if (!$for_plaintext) {
+                       $escaped = [];
+
+                       // Escaping BBCodes susceptible to contain rogue URL we don'' want the autolinker to catch
+                       $text = preg_replace_callback('#\[(url|img|audio|video|youtube|vimeo|share|attachment|iframe|bookmark).+?\[/\1\]#ism',
+                               function ($matches) use (&$escaped) {
+                                       $return = '{escaped-' . count($escaped) . '}';
+                                       $escaped[] = $matches[0];
+
+                                       return $return;
+                               },
+                               $text
+                       );
+
                        // Autolinker for isolated URLs
                        $text = preg_replace(Strings::autoLinkRegEx(), '[url]$1[/url]', $text);
+
+                       // Restoring escaped blocks
+                       $text = preg_replace_callback('/{escaped-([0-9]+)}/iU',
+                               function ($matches) use ($escaped) {
+                                       return $escaped[intval($matches[1])] ?? $matches[0];
+                               },
+                               $text
+                       );
                }
 
                // This is actually executed in Item::prepareBody()
@@ -1610,7 +1631,7 @@ class BBCode extends BaseObject
                //$Text = preg_replace("/\[crypt=(.*?)\](.*?)\[\/crypt\]/ism", '<br/><img src="' .System::baseUrl() . '/images/lock_icon.gif" alt="' . L10n::t('Encrypted content') . '" title="' . '$1' . ' ' . L10n::t('Encrypted content') . '" /><br />', $Text);
 
                // Simplify "video" element
-               $text = preg_replace("(\[video.*?\s?src\s?=\s?([^\s\]]*).*?\].*?\[\/video\\])ism", "[video]$1[/video]", $text);
+               $text = preg_replace('(\[video.*?\ssrc\s?=\s?([^\s\]]+).*?\].*?\[/video\])ism', '[video]$1[/video]', $text);
 
                // Try to Oembed
                if ($try_oembed) {
@@ -2031,9 +2052,6 @@ class BBCode extends BaseObject
                        $text = self::convert($text, false, 4);
                }
 
-               // mask some special HTML chars from conversation to markdown
-               $text = str_replace(['&lt;', '&gt;', '&amp;'], ['&_lt_;', '&_gt_;', '&_amp_;'], $text);
-
                // If a link is followed by a quote then there should be a newline before it
                // Maybe we should make this newline at every time before a quote.
                $text = str_replace(['</a><blockquote>'], ['</a><br><blockquote>'], $text);
@@ -2043,9 +2061,6 @@ class BBCode extends BaseObject
                // Now convert HTML to Markdown
                $text = HTML::toMarkdown($text);
 
-               // unmask the special chars back to HTML
-               $text = str_replace(['&\_lt\_;', '&\_gt\_;', '&\_amp\_;'], ['&lt;', '&gt;', '&amp;'], $text);
-
                $a->getProfiler()->saveTimestamp($stamp1, "parser", System::callstack());
 
                // Libertree has a problem with escaped hashtags.