Make HtmlOutputNodeImg::getHostMatcher() reusable as Url::getHostnameMatcher()
authorTim Düsterhus <duesterhus@woltlab.com>
Fri, 5 Mar 2021 15:41:01 +0000 (16:41 +0100)
committerTim Düsterhus <duesterhus@woltlab.com>
Fri, 5 Mar 2021 15:43:54 +0000 (16:43 +0100)
wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeImg.class.php
wcfsetup/install/files/lib/util/Url.class.php

index 0f16d95070ae7a511a7e65ff18068160d374b657..f6439a609a6698a7e9cccdefe9f73013dfcceccc 100644 (file)
@@ -195,56 +195,11 @@ class HtmlOutputNodeImg extends AbstractHtmlOutputNode
     }
 
     /**
-     * Returns a function that matches hosts against the given whitelist.
-     * The whitelist supports wildcards using using `*.` prefix.
-     *
-     * @param string[] $whitelist
-     * @return      callable
+     * @deprecated 5.4 Use Url::getHostnameMatcher().
      */
-    protected function getHostMatcher(array $whitelist)
+    protected function getHostMatcher(array $hostnames)
     {
-        $hosts = [];
-        foreach ($whitelist as $host) {
-            $isWildcard = false;
-            if (\mb_strpos($host, '*') !== false) {
-                $host = \preg_replace('~^(\*\.)+~', '', $host);
-                if (\mb_strpos($host, '*') !== false || $host === '') {
-                    // bad host
-                    continue;
-                }
-
-                $isWildcard = true;
-            }
-
-            $host = \mb_strtolower($host);
-            if (!isset($hosts[$host])) {
-                $hosts[$host] = $isWildcard;
-            }
-        }
-
-        return static function ($hostname) use ($hosts) {
-            static $validHosts = [];
-
-            $hostname = \mb_strtolower($hostname);
-            if (isset($hosts[$hostname]) || isset($validHosts[$hostname])) {
-                return true;
-            } else {
-                // check wildcard hosts
-                foreach ($hosts as $host => $isWildcard) {
-                    if ($isWildcard && \mb_strpos($hostname, $host) !== false) {
-                        // the prepended dot will ensure that `example.com` matches only
-                        // on domains like `foo.example.com` but not on `bar-example.com`
-                        if (StringUtil::endsWith($hostname, '.' . $host)) {
-                            $validHosts[$hostname] = $hostname;
-
-                            return true;
-                        }
-                    }
-                }
-            }
-
-            return false;
-        };
+        return Url::getHostnameMatcher($hostnames);
     }
 
     /**
@@ -266,7 +221,7 @@ class HtmlOutputNodeImg extends AbstractHtmlOutputNode
                 $whitelist[] = $host;
             }
 
-            $matcher = $this->getHostMatcher($whitelist);
+            $matcher = Url::getHostnameMatcher($whitelist);
         }
 
         return $matcher($hostname);
@@ -303,7 +258,7 @@ class HtmlOutputNodeImg extends AbstractHtmlOutputNode
                 $whitelist[] = $host;
             }
 
-            $matcher = $this->getHostMatcher($whitelist);
+            $matcher = Url::getHostnameMatcher($whitelist);
         }
 
         $host = Url::parse($src)['host'];
index 8b0ac217e00b2944b59dca588efc8855d4323f76..4a0b0aec8d92a3244cf0829120f98266bae39def 100644 (file)
@@ -168,4 +168,56 @@ final class Url implements \ArrayAccess
 
         throw new \RuntimeException("Unknown url component offset '" . $property . "'.");
     }
+
+    /**
+     * Returns a matcher that decides whether the URL matches the given list of hostnames. Hostnames may contain an
+     * optional wildcard prefix (`*.`).
+     *
+     * @since 5.4
+     */
+    public static function getHostnameMatcher(array $hostnames): callable
+    {
+        $hosts = [];
+        foreach ($hostnames as $host) {
+            $isWildcard = false;
+            if (\mb_strpos($host, '*') !== false) {
+                $host = \preg_replace('~^(\*\.)+~', '', $host);
+                if (\mb_strpos($host, '*') !== false || $host === '') {
+                    // bad host
+                    continue;
+                }
+
+                $isWildcard = true;
+            }
+
+            $host = \mb_strtolower($host);
+            if (!isset($hosts[$host])) {
+                $hosts[$host] = $isWildcard;
+            }
+        }
+
+        return static function ($hostname) use ($hosts) {
+            static $validHosts = [];
+
+            $hostname = \mb_strtolower($hostname);
+            if (isset($hosts[$hostname]) || isset($validHosts[$hostname])) {
+                return true;
+            } else {
+                // check wildcard hosts
+                foreach ($hosts as $host => $isWildcard) {
+                    if ($isWildcard && \mb_strpos($hostname, $host) !== false) {
+                        // the prepended dot will ensure that `example.com` matches only
+                        // on domains like `foo.example.com` but not on `bar-example.com`
+                        if (StringUtil::endsWith($hostname, '.' . $host)) {
+                            $validHosts[$hostname] = $hostname;
+
+                            return true;
+                        }
+                    }
+                }
+            }
+
+            return false;
+        };
+    }
 }