From 86ccd99f375d10063cefe1f5d4e46c21039552fd Mon Sep 17 00:00:00 2001
From: Benni Mack <benni@typo3.org>
Date: Fri, 13 Aug 2021 13:01:03 +0200
Subject: [PATCH] [BUGFIX] PSR-7 Uri implementation must return scheme as
 string

TYPO3's PSR-7 implementation has a small flaw when having URLs
without a scheme, which should always return an empty string.

This change initializes the scheme with an empty string by default.

Resolves: #94872
Releases: master, 10.4
Change-Id: If2898d697f37e6e5fc8c4553d0bb500f7fc8b47e
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/70547
Tested-by: Benjamin Franzke <bfr@qbus.de>
Tested-by: core-ci <typo3@b13.com>
Tested-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Reviewed-by: Benjamin Franzke <bfr@qbus.de>
Reviewed-by: Andreas Fernandez <a.fernandez@scripting-base.de>
---
 typo3/sysext/core/Classes/Http/Uri.php            | 2 +-
 typo3/sysext/core/Classes/Routing/SiteMatcher.php | 4 ++--
 typo3/sysext/core/Classes/Site/Entity/Site.php    | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/typo3/sysext/core/Classes/Http/Uri.php b/typo3/sysext/core/Classes/Http/Uri.php
index 16e6fd6cfe52..8390cf59f64f 100644
--- a/typo3/sysext/core/Classes/Http/Uri.php
+++ b/typo3/sysext/core/Classes/Http/Uri.php
@@ -45,7 +45,7 @@ class Uri implements UriInterface
      * The default scheme for the URI
      * @var string
      */
-    protected $scheme;
+    protected $scheme = '';
 
     /**
      * @var int[] Associative array containing schemes and their default ports.
diff --git a/typo3/sysext/core/Classes/Routing/SiteMatcher.php b/typo3/sysext/core/Classes/Routing/SiteMatcher.php
index c9a21fb67893..f34bd8c200af 100644
--- a/typo3/sysext/core/Classes/Routing/SiteMatcher.php
+++ b/typo3/sysext/core/Classes/Routing/SiteMatcher.php
@@ -189,7 +189,7 @@ class SiteMatcher implements SingletonInterface
                 array_filter(['tail' => '.*', 'port' => (string)$uri->getPort()]),
                 ['utf8' => true],
                 $uri->getHost() ?: '',
-                $uri->getScheme()
+                $uri->getScheme() === '' ? [] : [$uri->getScheme()]
             );
             $identifier = 'site_' . $site->getIdentifier();
             $groupedRoutes[($uri->getScheme() ?: '-') . ($uri->getHost() ?: '-')][$uri->getPath() ?: '/'][$identifier] = $route;
@@ -202,7 +202,7 @@ class SiteMatcher implements SingletonInterface
                     array_filter(['tail' => '.*', 'port' => (string)$uri->getPort()]),
                     ['utf8' => true],
                     (string)idn_to_ascii($uri->getHost()),
-                    $uri->getScheme()
+                    $uri->getScheme() === '' ? [] : [$uri->getScheme()]
                 );
                 $identifier = 'site_' . $site->getIdentifier() . '_' . $siteLanguage->getLanguageId();
                 $groupedRoutes[($uri->getScheme() ?: '-') . ($uri->getHost() ?: '-')][$uri->getPath() ?: '/'][$identifier] = $route;
diff --git a/typo3/sysext/core/Classes/Site/Entity/Site.php b/typo3/sysext/core/Classes/Site/Entity/Site.php
index 3d20c20f2a70..a54afd446cb9 100644
--- a/typo3/sysext/core/Classes/Site/Entity/Site.php
+++ b/typo3/sysext/core/Classes/Site/Entity/Site.php
@@ -114,7 +114,7 @@ class Site implements SiteInterface
                 );
                 $base = new Uri($this->sanitizeBaseUrl($base));
                 // no host given by the language-specific base, so lets prefix the main site base
-                if ($base->getScheme() === null && $base->getHost() === '') {
+                if ($base->getScheme() === '' && $base->getHost() === '') {
                     $base = rtrim((string)$this->base, '/') . '/' . ltrim((string)$base, '/');
                     $base = new Uri($this->sanitizeBaseUrl($base));
                 }
-- 
GitLab