Commit 0feb1eec authored by Benni Mack's avatar Benni Mack Committed by Andreas Fernandez
Browse files

[BUGFIX] Make php-intl work with older ICU versions

On old OS with ICU < 4.6, the constant INTL_IDNA_VARIANT_UTS46
is not available, even if php-intl is installed.

Therefore, a wrapper is created in HttpUtility to check
if the constant is available, then uses INTL_IDNA_VARIANT_UTS46
otherwise the 2003 version of the HttpUtility.

Also see the section about INTL_IDNA_VARIANT_UTS46 within
https://www.php.net/manual/en/intl.constants.php

Resolves: #87953
Releases: master, 9.5
Change-Id: I594c0ffd9afa115de595b0c027bf2474c3abfafb
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/60710

Reviewed-by: Sven Juergens's avatarSven Juergens <typo3@blue-side.de>
Reviewed-by: default avatarKevin Meckl <kevin.meckl@zdrei.com>
Reviewed-by: default avatarTimo Poppinga <timo.poppinga@zdrei.com>
Reviewed-by: Andreas Fernandez's avatarAndreas Fernandez <a.fernandez@scripting-base.de>
Tested-by: default avatarTYPO3com <noreply@typo3.com>
Tested-by: default avatarTimo Poppinga <timo.poppinga@zdrei.com>
Tested-by: Andreas Fernandez's avatarAndreas Fernandez <a.fernandez@scripting-base.de>
parent e845d90b
......@@ -55,6 +55,7 @@ use TYPO3\CMS\Core\Type\Bitmask\Permission;
use TYPO3\CMS\Core\Utility\ArrayUtility;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\HttpUtility;
use TYPO3\CMS\Core\Utility\MathUtility;
use TYPO3\CMS\Core\Utility\StringUtility;
use TYPO3\CMS\Core\Versioning\VersionState;
......@@ -2604,7 +2605,7 @@ class DataHandler implements LoggerAwareInterface
break;
case 'domainname':
if (!preg_match('/^[a-z0-9.\\-]*$/i', $value)) {
$value = (string)idn_to_ascii($value, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46);
$value = (string)HttpUtility::idn_to_ascii($value);
}
break;
case 'email':
......
......@@ -14,6 +14,7 @@ namespace TYPO3\CMS\Core\Mail;
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Core\Utility\HttpUtility;
use TYPO3\CMS\Core\Utility\MailUtility;
/**
......@@ -265,7 +266,7 @@ class MailMessage extends \Swift_Message
}
$domain = substr($email, $atPosition + 1);
$local = substr($email, 0, $atPosition);
$domain = (string)idn_to_ascii($domain, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46);
$domain = (string)HttpUtility::idn_to_ascii($domain);
return $local . '@' . $domain;
}
......
......@@ -30,6 +30,7 @@ use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
use TYPO3\CMS\Core\Site\PseudoSiteFinder;
use TYPO3\CMS\Core\Site\SiteFinder;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\HttpUtility;
use TYPO3\CMS\Core\Utility\RootlineUtility;
/**
......@@ -135,7 +136,7 @@ class SiteMatcher implements SingletonInterface
$context = new RequestContext(
'',
$request->getMethod(),
idn_to_ascii($request->getUri()->getHost(), IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46),
HttpUtility::idn_to_ascii($request->getUri()->getHost()),
$request->getUri()->getScheme(),
// Ports are only necessary for URL generation in Symfony which is not used by TYPO3
80,
......@@ -235,7 +236,7 @@ class SiteMatcher implements SingletonInterface
['site' => $site, 'language' => $siteLanguage, 'tail' => ''],
array_filter(['tail' => '.*', 'port' => (string)$uri->getPort()]),
['utf8' => true],
idn_to_ascii($uri->getHost(), IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46) ?: '',
HttpUtility::idn_to_ascii($uri->getHost()) ?: '',
$uri->getScheme()
);
$identifier = 'site_' . $site->getIdentifier() . '_' . $siteLanguage->getLanguageId();
......
......@@ -867,7 +867,7 @@ class GeneralUtility
$domain = substr($email, $atPosition + 1);
$user = substr($email, 0, $atPosition);
if (!preg_match('/^[a-z0-9.\\-]*$/i', $domain)) {
$domain = idn_to_ascii($domain, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46);
$domain = HttpUtility::idn_to_ascii($domain);
if ($domain === false) {
return false;
}
......@@ -895,11 +895,11 @@ class GeneralUtility
if ($atPosition !== false) {
$domain = substr($value, $atPosition + 1);
$local = substr($value, 0, $atPosition);
$domain = (string)idn_to_ascii($domain, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46);
$domain = (string)HttpUtility::idn_to_ascii($domain);
// Return if no @ found or it is placed at the very beginning or end of the email
return $local . '@' . $domain;
}
return (string)idn_to_ascii($value, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46);
return (string)HttpUtility::idn_to_ascii($value);
}
/**
......@@ -982,7 +982,7 @@ class GeneralUtility
return false;
}
if (isset($parsedUrl['host']) && !preg_match('/^[a-z0-9.\\-]*$/i', $parsedUrl['host'])) {
$host = idn_to_ascii($parsedUrl['host'], IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46);
$host = HttpUtility::idn_to_ascii($parsedUrl['host']);
if ($host === false) {
return false;
}
......
......@@ -178,4 +178,22 @@ class HttpUtility
return $queryString && $prependCharacter ? $prependCharacter . $queryString : $queryString;
}
/**
* Compatibility layer for PHP versions running ICU 4.4, as the constant INTL_IDNA_VARIANT_UTS46
* is only available as of ICU 4.6.
*
* Please note: Once PHP 7.4 is the minimum requirement, this method will vanish without further notice
* as it is recommended to use the native method instead, when working against a clean environment.
*
* @param string $domain the domain name to convert Punicode to ASCII.
* @return string|bool
*/
public static function idn_to_ascii(string $domain)
{
if (defined('INTL_IDNA_VARIANT_UTS46')) {
return idn_to_ascii($domain, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46);
}
return idn_to_ascii($domain);
}
}
......@@ -469,7 +469,7 @@ class PageLinkBuilder extends AbstractTypolinkBuilder
$target = $target ?: $this->resolveTargetAttribute($conf, 'extTarget', false, $tsfe->extTarget);
// Convert IDNA-like domain (if any)
if (!preg_match('/^[a-z0-9.\\-]*$/i', $targetDomain)) {
$targetDomain = (string)idn_to_ascii($targetDomain, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46);
$targetDomain = HttpUtility::idn_to_ascii($targetDomain);
}
$url = $absoluteUrlScheme . '://' . $targetDomain . '/index.php?id=' . $page['uid'] . $additionalQueryParams;
} else {
......
......@@ -17,6 +17,7 @@ namespace TYPO3\CMS\Linkvalidator\Linktype;
use GuzzleHttp\Cookie\CookieJar;
use TYPO3\CMS\Core\Http\RequestFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\HttpUtility;
/**
* This class provides Check External Links plugin implementation
......@@ -207,6 +208,6 @@ class ExternalLinktype extends AbstractLinktype
*/
protected function preprocessUrl(string $url): string
{
return (string)idn_to_ascii($url, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46);
return (string)HttpUtility::idn_to_ascii($url);
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment