Merge branch 'master' into next
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / system / html / metacode / converter / UrlMetacodeConverter.class.php
index e8aaf923c10e46100ab325685d775f66edefd2a3..a6cac83491b200a7bc02f2ecb9c644a8b677b11d 100644 (file)
@@ -13,6 +13,12 @@ use wcf\util\StringUtil;
  * @since       3.0
  */
 class UrlMetacodeConverter extends AbstractMetacodeConverter {
+       /**
+        * list of allowed schemas as defined by HTMLPurifier
+        * @var string[] 
+        */
+       public static $allowedSchemes = ['http', 'https', 'mailto', 'ftp', 'nntp', 'news', 'tel', 'steam', 'ts3server'];
+       
        /**
         * @inheritDoc
         */
@@ -25,6 +31,20 @@ class UrlMetacodeConverter extends AbstractMetacodeConverter {
                }
                
                $href = StringUtil::decodeHTML($href);
+               if (mb_strpos($href, '//') === 0) {
+                       // dynamic protocol, treat as https
+                       $href = "https:{$href}";
+               }
+               else if (preg_match('~^(?P<schema>[a-z0-9]+)://~', $href, $match)) {
+                       if (!in_array($match['schema'], self::$allowedSchemes)) {
+                               // invalid schema, replace it with `http`
+                               $href = 'http' . mb_substr($href, strlen($match['schema']));
+                       }
+               }
+               else if (mb_strpos($href, 'index.php') === false) {
+                       // unless it's a relative `index.php` link, assume it is missing the protocol
+                       $href = "http://{$href}";
+               }
                
                // check if the link is empty, use the href value instead
                $useHrefAsValue = false;