From c86acfb2af7c064c9c5a307644ea9835baa84189 Mon Sep 17 00:00:00 2001 From: Oliver Hader <oliver@typo3.org> Date: Thu, 10 Mar 2022 12:08:49 +0100 Subject: [PATCH] [BUGFIX] Use defaultScheme setting instead of hard-coded 'http' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Several places in the TYPO3 core fall back to using 'http' as protocol for links in case none was given. In order to adjust this behavior new $GLOBALS['TYPO3_CONF_VARS']['SYS']['defaultScheme'] setting has been introduced, which uses 'http' as default. In order to adjust the default protocol, one has to add the following assignment to their LocalConfiguration.php settings: $GLOBALS['TYPO3_CONF_VARS']['SYS']['defaultScheme'] = 'https' Resolves: #97111 Releases: main, 11.5 Change-Id: I8c86a3b98dfdfef96c6e433de28e24c1af7f27ab Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/73867 Reviewed-by: Oliver Klee <typo3-coding@oliverklee.de> Reviewed-by: Stefan Bürk <stefan@buerk.tech> Reviewed-by: Nikita Hovratov <nikita.h@live.de> Tested-by: Stefan Bürk <stefan@buerk.tech> Tested-by: core-ci <typo3@b13.com> Tested-by: Nikita Hovratov <nikita.h@live.de> --- Build/phpstan/phpstan-baseline.neon | 5 -- .../LegacyLinkNotationConverter.php | 2 +- .../LinkHandling/LinkHandlingInterface.php | 7 +++ .../Classes/LinkHandling/UrlLinkHandler.php | 16 ++++-- .../Configuration/DefaultConfiguration.php | 1 + .../DefaultConfigurationDescription.yaml | 6 +++ .../Important-97111-DefaultURIScheme.rst | 24 +++++++++ .../12.0/Important-97111-DefaultURIScheme.rst | 24 +++++++++ .../Unit/LinkHandling/UrlLinkHandlerTest.php | 52 ++++++++++++++----- 9 files changed, 116 insertions(+), 21 deletions(-) create mode 100644 typo3/sysext/core/Documentation/Changelog/11.5.x/Important-97111-DefaultURIScheme.rst create mode 100644 typo3/sysext/core/Documentation/Changelog/12.0/Important-97111-DefaultURIScheme.rst diff --git a/Build/phpstan/phpstan-baseline.neon b/Build/phpstan/phpstan-baseline.neon index 5eafaffb109b..5ac247ea6e9a 100644 --- a/Build/phpstan/phpstan-baseline.neon +++ b/Build/phpstan/phpstan-baseline.neon @@ -1715,11 +1715,6 @@ parameters: count: 1 path: ../../typo3/sysext/core/Tests/Unit/LinkHandling/FolderLinkHandlerTest.php - - - message: "#^Parameter \\#1 \\$data of method TYPO3\\\\CMS\\\\Core\\\\LinkHandling\\\\UrlLinkHandler\\:\\:resolveHandlerData\\(\\) expects array, string given\\.$#" - count: 1 - path: ../../typo3/sysext/core/Tests/Unit/LinkHandling/UrlLinkHandlerTest.php - - message: "#^Parameter \\#2 \\$locale of function setlocale expects array\\|string\\|null, int given\\.$#" count: 3 diff --git a/typo3/sysext/core/Classes/LinkHandling/LegacyLinkNotationConverter.php b/typo3/sysext/core/Classes/LinkHandling/LegacyLinkNotationConverter.php index 0208149d8452..a13be8bd09c4 100644 --- a/typo3/sysext/core/Classes/LinkHandling/LegacyLinkNotationConverter.php +++ b/typo3/sysext/core/Classes/LinkHandling/LegacyLinkNotationConverter.php @@ -135,7 +135,7 @@ class LegacyLinkNotationConverter // url (external): If doubleSlash or if a '.' comes before a '/'. if (!$isIdOrAlias && $isLocalFile !== 1 && $urlChar && (!$containsSlash || $urlChar < $fileChar)) { $result['type'] = LinkService::TYPE_URL; - $result['url'] = 'http://' . $linkParameter; + $result['url'] = UrlLinkHandler::getDefaultScheme() . '://' . $linkParameter; // file (internal) or folder } elseif ($containsSlash || $isLocalFile) { $result = $this->getFileOrFolderObjectFromMixedIdentifier($linkParameter); diff --git a/typo3/sysext/core/Classes/LinkHandling/LinkHandlingInterface.php b/typo3/sysext/core/Classes/LinkHandling/LinkHandlingInterface.php index 33fa833af5b0..513b2461662c 100644 --- a/typo3/sysext/core/Classes/LinkHandling/LinkHandlingInterface.php +++ b/typo3/sysext/core/Classes/LinkHandling/LinkHandlingInterface.php @@ -24,6 +24,13 @@ namespace TYPO3\CMS\Core\LinkHandling; */ interface LinkHandlingInterface { + /** + * @var non-empty-string will be used for links without a scheme if no default scheme is configured + * + * @internal Do not use directly; please use `UrlLinkHandler::getDefaultScheme()` instead to also take the + * configured default scheme into account. + */ + public const DEFAULT_SCHEME = 'http'; /** * Returns a string interpretation of the link href query from objects, something like diff --git a/typo3/sysext/core/Classes/LinkHandling/UrlLinkHandler.php b/typo3/sysext/core/Classes/LinkHandling/UrlLinkHandler.php index 64dde174e9d1..7a0df4f5e115 100644 --- a/typo3/sysext/core/Classes/LinkHandling/UrlLinkHandler.php +++ b/typo3/sysext/core/Classes/LinkHandling/UrlLinkHandler.php @@ -44,7 +44,7 @@ class UrlLinkHandler implements LinkHandlingInterface } /** - * Ensures that a scheme is always added, if www.typo3.org was added previously + * Ensures that a scheme is always added, if www.typo3.org was added previously. * * @param string $url the URL * @return string @@ -57,8 +57,7 @@ class UrlLinkHandler implements LinkHandlingInterface } $scheme = parse_url($url, PHP_URL_SCHEME); if (empty($scheme)) { - $url = 'http://' . $url; - // 'java{TAB}script:' is parsed as empty URL scheme, thus not ending up here + $url = self::getDefaultScheme() . '://' . $url; } elseif (in_array(strtolower($scheme), ['javascript', 'data'], true)) { // deny using insecure scheme's like `javascript:` or `data:` as URL scheme $url = ''; @@ -66,4 +65,15 @@ class UrlLinkHandler implements LinkHandlingInterface } return $url; } + + /** + * Returns the scheme (e.g. `http`) to be used for links with URLs without a scheme, e.g., for `www.example.com`. + * + * @return non-empty-string + */ + public static function getDefaultScheme(): string + { + return ($GLOBALS['TYPO3_CONF_VARS']['SYS']['defaultScheme'] ?? '') + ?: LinkHandlingInterface::DEFAULT_SCHEME; + } } diff --git a/typo3/sysext/core/Configuration/DefaultConfiguration.php b/typo3/sysext/core/Configuration/DefaultConfiguration.php index a3735162746b..7253ac216406 100644 --- a/typo3/sysext/core/Configuration/DefaultConfiguration.php +++ b/typo3/sysext/core/Configuration/DefaultConfiguration.php @@ -379,6 +379,7 @@ return [ ], ], ], + 'defaultScheme' => \TYPO3\CMS\Core\LinkHandling\LinkHandlingInterface::DEFAULT_SCHEME, 'linkHandler' => [ // Array: Available link types, class which implement the LinkHandling interface 'page' => \TYPO3\CMS\Core\LinkHandling\PageLinkHandler::class, 'file' => \TYPO3\CMS\Core\LinkHandling\FileLinkHandler::class, diff --git a/typo3/sysext/core/Configuration/DefaultConfigurationDescription.yaml b/typo3/sysext/core/Configuration/DefaultConfigurationDescription.yaml index 845b701aab6d..12ef31c77552 100644 --- a/typo3/sysext/core/Configuration/DefaultConfigurationDescription.yaml +++ b/typo3/sysext/core/Configuration/DefaultConfigurationDescription.yaml @@ -93,6 +93,12 @@ SYS: hhmm: type: text description: 'Format of Hours-Minutes - see PHP-function <a href="https://php.net/date" target="_blank" rel="noreferrer">date()</a>' + defaultScheme: + type: text + allowedValues: + 'http': 'http' + 'https': 'https' + description: 'Default URI scheme to be used in case none was given, e.g. "www.typo3.org" becomes "http://www.typo3.org"' loginCopyrightWarrantyProvider: type: text description: 'If you provide warranty for TYPO3 to your customers insert you (company) name here. It will appear in the login-dialog as the warranty provider. (You must also set URL below).' diff --git a/typo3/sysext/core/Documentation/Changelog/11.5.x/Important-97111-DefaultURIScheme.rst b/typo3/sysext/core/Documentation/Changelog/11.5.x/Important-97111-DefaultURIScheme.rst new file mode 100644 index 000000000000..c8b53c8b874e --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/11.5.x/Important-97111-DefaultURIScheme.rst @@ -0,0 +1,24 @@ +.. include:: /Includes.rst.txt + +.. _important-97111-1657214951: + +====================================== +Important: #97111 - Default URI scheme +====================================== + +See :issue:`97111` + +Description +=========== + +Several places in the TYPO3 core fall back to using `http` as a protocol for +links in case none was given. In order to adjust this behavior the new +:php:`$GLOBALS['TYPO3_CONF_VARS']['SYS']['defaultScheme']` setting has been +introduced, which uses `http` as default. + +In order to adjust the default protocol, one has to add the following +assignment to their :file:`typo3conf/LocalConfiguration.php` settings: + +:php:`$GLOBALS['TYPO3_CONF_VARS']['SYS']['defaultScheme'] = 'https'` + +.. index:: LocalConfiguration, RTE, ext:core diff --git a/typo3/sysext/core/Documentation/Changelog/12.0/Important-97111-DefaultURIScheme.rst b/typo3/sysext/core/Documentation/Changelog/12.0/Important-97111-DefaultURIScheme.rst new file mode 100644 index 000000000000..c8b53c8b874e --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/12.0/Important-97111-DefaultURIScheme.rst @@ -0,0 +1,24 @@ +.. include:: /Includes.rst.txt + +.. _important-97111-1657214951: + +====================================== +Important: #97111 - Default URI scheme +====================================== + +See :issue:`97111` + +Description +=========== + +Several places in the TYPO3 core fall back to using `http` as a protocol for +links in case none was given. In order to adjust this behavior the new +:php:`$GLOBALS['TYPO3_CONF_VARS']['SYS']['defaultScheme']` setting has been +introduced, which uses `http` as default. + +In order to adjust the default protocol, one has to add the following +assignment to their :file:`typo3conf/LocalConfiguration.php` settings: + +:php:`$GLOBALS['TYPO3_CONF_VARS']['SYS']['defaultScheme'] = 'https'` + +.. index:: LocalConfiguration, RTE, ext:core diff --git a/typo3/sysext/core/Tests/Unit/LinkHandling/UrlLinkHandlerTest.php b/typo3/sysext/core/Tests/Unit/LinkHandling/UrlLinkHandlerTest.php index b5a03f9106b8..61be21832fff 100644 --- a/typo3/sysext/core/Tests/Unit/LinkHandling/UrlLinkHandlerTest.php +++ b/typo3/sysext/core/Tests/Unit/LinkHandling/UrlLinkHandlerTest.php @@ -17,6 +17,7 @@ declare(strict_types=1); namespace TYPO3\CMS\Core\Tests\Unit\LinkHandling; +use TYPO3\CMS\Core\LinkHandling\LinkHandlingInterface; use TYPO3\CMS\Core\LinkHandling\UrlLinkHandler; use TYPO3\TestingFramework\Core\Unit\UnitTestCase; @@ -115,14 +116,9 @@ class UrlLinkHandlerTest extends UnitTestCase /** * @test * - * @param string $input - * @param array $expected - * @param string $finalString - * * @dataProvider resolveParametersForNonFilesDataProvider - * @todo Defining the method parameter types results in test bench errors */ - public function resolveReturnsSplitParameters($input, $expected, $finalString): void + public function resolveReturnsSplitParameters(array $input, array $expected, string $finalString): void { $subject = new UrlLinkHandler(); self::assertEquals($expected, $subject->resolveHandlerData($input)); @@ -131,16 +127,48 @@ class UrlLinkHandlerTest extends UnitTestCase /** * @test * - * @param string $input - * @param array $parameters - * @param string $expected - * * @dataProvider resolveParametersForNonFilesDataProvider - * @todo Defining the method parameter types results in test bench errors */ - public function splitParametersToUnifiedIdentifier($input, $parameters, $expected): void + public function splitParametersToUnifiedIdentifier(array $input, array $parameters, string $expected): void { $subject = new UrlLinkHandler(); self::assertEquals($expected, $subject->asString($parameters)); } + + /** + * @test + */ + public function getDefaultSchemeForNoSchemeInConfigurationReturnsFallbackScheme(): void + { + unset($GLOBALS['TYPO3_CONF_VARS']['SYS']['defaultScheme']); + + $result = UrlLinkHandler::getDefaultScheme(); + + self::assertSame(LinkHandlingInterface::DEFAULT_SCHEME, $result); + } + + /** + * @test + */ + public function getDefaultSchemeForEmptySchemeInConfigurationReturnsFallbackScheme(): void + { + $GLOBALS['TYPO3_CONF_VARS']['SYS']['defaultScheme'] = ''; + + $result = UrlLinkHandler::getDefaultScheme(); + + self::assertSame(LinkHandlingInterface::DEFAULT_SCHEME, $result); + } + + /** + * @test + */ + public function getDefaultSchemeForSchemeInConfigurationReturnsSchemeFromConfiguration(): void + { + $scheme = 'https'; + $GLOBALS['TYPO3_CONF_VARS']['SYS']['defaultScheme'] = $scheme; + + $result = UrlLinkHandler::getDefaultScheme(); + + self::assertSame($scheme, $result); + } } -- GitLab