From 44fc8221d30d5d8c3a69f08e62266948cfad2232 Mon Sep 17 00:00:00 2001 From: Benni Mack <benni@typo3.org> Date: Tue, 17 Jan 2023 23:20:19 +0100 Subject: [PATCH] [BUGFIX] Avoid logging of invalid locales in site configuration TYPO3's log is mostly covered with "Locale fr_FR.UTF-8 not found", which can be simplified, if setlocale() is not working properly. The POSIX Platform suffix "UTF-8" is then removed, and setlocale() is called again with "fr_FR" instead of "fr_FR.UTF-8" thus avoiding log flooding in some systems. Resolves: #99591 Releases: main, 11.5, 10.4 Change-Id: I4609d453c29a306d448bcdc3277b51a344af28ae Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/77434 Tested-by: core-ci <typo3@b13.com> Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de> Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de> --- .../core/Classes/Localization/Locales.php | 34 ++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/typo3/sysext/core/Classes/Localization/Locales.php b/typo3/sysext/core/Classes/Localization/Locales.php index 2361be6d8d14..e436025e05f7 100644 --- a/typo3/sysext/core/Classes/Localization/Locales.php +++ b/typo3/sysext/core/Classes/Localization/Locales.php @@ -264,10 +264,25 @@ class Locales implements SingletonInterface public static function setSystemLocaleFromSiteLanguage(SiteLanguage $siteLanguage): bool { $locale = $siteLanguage->getLocale(); - // No locale was given, so return false; + // No locale was given, so return false if (!$locale) { return false; } + return self::setLocale($locale, $locale); + } + + /** + * Internal method, which calls itself again, in order to avoid multiple logging issues. + * The main reason for this method is that it calls itself again by trying again to set + * the locale. Due to sensible defaults, people used the locale "de_AT.utf-8" with the POSIX platform + * (see https://en.wikipedia.org/wiki/Locale_(computer_software)#POSIX_platforms) in their site configuration, + * even though the target system has "de_AT" and not "de_AT.UTF-8" defined. + * "setLocale()" is now called again without the POSIX platform suffix and is checked again if the locale + * is then available, and then logs the failed information. + */ + protected static function setLocale(string $locale, string $localeStringForTrigger): bool + { + $incomingLocale = $locale; $availableLocales = GeneralUtility::trimExplode(',', $locale, true); // If LC_NUMERIC is set e.g. to 'de_DE' PHP parses float values locale-aware resulting in strings with comma // as decimal point which causes problems with value conversions - so we set all locale types except LC_NUMERIC @@ -283,9 +298,20 @@ class Locales implements SingletonInterface setlocale(LC_MONETARY, ...$availableLocales); setlocale(LC_TIME, ...$availableLocales); } else { - GeneralUtility::makeInstance(LogManager::class) - ->getLogger(__CLASS__) - ->error('Locale "' . htmlspecialchars($siteLanguage->getLocale()) . '" not found.'); + // Retry again without the "utf-8" POSIX platform suffix if this is given. + if (str_contains($incomingLocale, '.')) { + [$localeWithoutModifier] = explode('.', $incomingLocale); + return self::setLocale($localeWithoutModifier, $incomingLocale); + } + if ($localeStringForTrigger === $locale) { + GeneralUtility::makeInstance(LogManager::class) + ->getLogger(__CLASS__) + ->error('Locale "' . htmlspecialchars($localeStringForTrigger) . '" not found.'); + } else { + GeneralUtility::makeInstance(LogManager::class) + ->getLogger(__CLASS__) + ->error('Locale "' . htmlspecialchars($localeStringForTrigger) . '" and "' . htmlspecialchars($incomingLocale) . '" not found.'); + } return false; } return true; -- GitLab