From 654480783001851ffc177ceabeac62737fe84453 Mon Sep 17 00:00:00 2001 From: Benni Mack <benni@typo3.org> Date: Thu, 28 May 2020 11:06:40 +0200 Subject: [PATCH] [!!!][TASK] Remove deprecated functionality in GeneralUtility The following deprecated methods are now removed: - \TYPO3\CMS\Core\Utility\GeneralUtility::compressIPv6 - \TYPO3\CMS\Core\Utility\GeneralUtility::flushDirectory - \TYPO3\CMS\Core\Utility\GeneralUtility::getApplicationContext - \TYPO3\CMS\Core\Utility\GeneralUtility::idnaEncode - \TYPO3\CMS\Core\Utility\GeneralUtility::IPv6Hex2Bin - \TYPO3\CMS\Core\Utility\GeneralUtility::IPv6Bin2Hex - \TYPO3\CMS\Core\Utility\GeneralUtility::isRunningOnCgiServerApi - \TYPO3\CMS\Core\Utility\GeneralUtility::linkThisUrl - \TYPO3\CMS\Core\Utility\GeneralUtility::milliseconds - \TYPO3\CMS\Core\Utility\GeneralUtility::presetApplicationContext - \TYPO3\CMS\Core\Utility\GeneralUtility::resetApplicationContext - \TYPO3\CMS\Core\Utility\GeneralUtility::verifyFilenameAgainstDenyPattern In addition, makeInstanceService requires the third parameter to be array instead of string or array. The method "getUrl()" now only accepts one argument. In addition, the testing framework is raised to 6.3.1 to not use the unneeded methods anymore. Resolves: #91513 Releases: master Change-Id: I124b6f531fed61a93f5ed03391e1d4b6cf7a08ae Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/64593 Tested-by: Andreas Fernandez <a.fernandez@scripting-base.de> Tested-by: TYPO3com <noreply@typo3.com> Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de> Reviewed-by: Andreas Fernandez <a.fernandez@scripting-base.de> Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de> --- composer.json | 2 +- composer.lock | 12 +- .../core/Classes/Utility/GeneralUtility.php | 308 +--------------- ...g-91473-DeprecatedFunctionalityRemoved.rst | 15 + .../Tests/Unit/Utility/GeneralUtilityTest.php | 6 +- .../Utility/GeneralUtilityTest.php | 343 ------------------ typo3/sysext/core/composer.json | 2 +- .../MethodArgumentDroppedStaticMatcher.php | 1 + .../Php/MethodCallStaticMatcher.php | 26 +- 9 files changed, 50 insertions(+), 665 deletions(-) delete mode 100644 typo3/sysext/core/Tests/UnitDeprecated/Utility/GeneralUtilityTest.php diff --git a/composer.json b/composer.json index 57fe60872038..7152b6dee008 100644 --- a/composer.json +++ b/composer.json @@ -89,7 +89,7 @@ "phpstan/phpstan": "^0.12.13", "rector/rector": "^0.7.14", "typo3/cms-styleguide": "~10.0.2", - "typo3/testing-framework": "^6.3.0" + "typo3/testing-framework": "^6.3.1" }, "suggest": { "ext-gd": "GDlib/Freetype is required for building images with text (GIFBUILDER) and can also be used to scale images", diff --git a/composer.lock b/composer.lock index 084063d0ed27..17cac2f410b9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "00b45341639bf5c1ef8e758d8ed4ef3c", + "content-hash": "1f351aa9a64f76cd6a045f6c8ccbafee", "packages": [ { "name": "cogpowered/finediff", @@ -7886,16 +7886,16 @@ }, { "name": "typo3/testing-framework", - "version": "6.3.0", + "version": "6.3.1", "source": { "type": "git", "url": "https://github.com/TYPO3/testing-framework.git", - "reference": "4e7339fafbf6439b542f2d070bb3d78ecdd1fc44" + "reference": "66973fd9f1cffb251d09b2ad13b7a788dd880b70" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/TYPO3/testing-framework/zipball/4e7339fafbf6439b542f2d070bb3d78ecdd1fc44", - "reference": "4e7339fafbf6439b542f2d070bb3d78ecdd1fc44", + "url": "https://api.github.com/repos/TYPO3/testing-framework/zipball/66973fd9f1cffb251d09b2ad13b7a788dd880b70", + "reference": "66973fd9f1cffb251d09b2ad13b7a788dd880b70", "shasum": "" }, "require": { @@ -7943,7 +7943,7 @@ "tests", "typo3" ], - "time": "2020-05-25T18:29:09+00:00" + "time": "2020-05-28T15:04:49+00:00" } ], "aliases": [], diff --git a/typo3/sysext/core/Classes/Utility/GeneralUtility.php b/typo3/sysext/core/Classes/Utility/GeneralUtility.php index 728dc0e440a0..4d0a3e336011 100644 --- a/typo3/sysext/core/Classes/Utility/GeneralUtility.php +++ b/typo3/sysext/core/Classes/Utility/GeneralUtility.php @@ -22,13 +22,10 @@ use Psr\Container\ContainerInterface; use Psr\Log\LoggerAwareInterface; use Psr\Log\LoggerInterface; use TYPO3\CMS\Core\Cache\CacheManager; -use TYPO3\CMS\Core\Core\ApplicationContext; use TYPO3\CMS\Core\Core\ClassLoadingInformation; use TYPO3\CMS\Core\Core\Environment; use TYPO3\CMS\Core\Http\RequestFactory; use TYPO3\CMS\Core\Log\LogManager; -use TYPO3\CMS\Core\Resource\Security\FileNameValidator; -use TYPO3\CMS\Core\Service\OpcodeCacheService; use TYPO3\CMS\Core\SingletonInterface; /** @@ -82,14 +79,6 @@ class GeneralUtility */ protected static $finalClassNameCache = []; - /** - * The application context - * - * @var \TYPO3\CMS\Core\Core\ApplicationContext - * @deprecated will be removed in TYPO3 v11. - */ - protected static $applicationContext; - /** * @var array<string, mixed> */ @@ -343,32 +332,6 @@ class GeneralUtility return false; } - /** - * Transform a regular IPv6 address from hex-representation into binary - * - * @param string $hex IPv6 address in hex-presentation - * @return string Binary representation (16 characters, 128 characters) - * @deprecated - will be removed in TYPO3 v11.0. Use the native PHP function inet_pton($hex) instead. - */ - public static function IPv6Hex2Bin($hex) - { - trigger_error('GeneralUtility::IPv6Hex2Bin() will be removed in TYPO3 v11.0. Use the native PHP function inet_pton($hex) instead.', E_USER_DEPRECATED); - return inet_pton($hex); - } - - /** - * Transform an IPv6 address from binary to hex-representation - * - * @param string $bin IPv6 address in hex-presentation - * @return string Binary representation (16 characters, 128 characters) - * @deprecated - will be removed in TYPO3 v11.0. Use the native PHP function inet_ntop($bin) instead. - */ - public static function IPv6Bin2Hex($bin) - { - trigger_error('GeneralUtility::IPv6Bin2Hex() will be removed in TYPO3 v11.0. Use the native PHP function inet_ntop($bin) instead.', E_USER_DEPRECATED); - return inet_ntop($bin); - } - /** * Normalize an IPv6 address to full length * @@ -431,20 +394,6 @@ class GeneralUtility return $normalizedAddress; } - /** - * Compress an IPv6 address to the shortest notation - * - * @param string $address Given IPv6 address - * @return string Compressed address - * @see normalizeIPv6() - * @deprecated will be removed in TYPO3 v11.0. Use the native PHP functions inet_ntop(inet_pton($address)) instead. - */ - public static function compressIPv6($address) - { - trigger_error('GeneralUtility::compressIPv6() will be removed in TYPO3 v11.0. Use the native PHP functions inet_ntop(inet_pton($address)) instead.', E_USER_DEPRECATED); - return inet_ntop(inet_pton($address)); - } - /** * Validate a given IP address. * @@ -853,33 +802,6 @@ class GeneralUtility return $validator->isValid($email, new RFCValidation()); } - /** - * Returns an ASCII string (punicode) representation of $value - * - * @param string $value - * @return string An ASCII encoded (punicode) string - * @deprecated since TYPO3 v10.0, will be removed in TYPO3 v11.0, use PHP's native idn_to_ascii($domain, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46) function directly. - */ - public static function idnaEncode($value) - { - trigger_error(__METHOD__ . ' will be removed in TYPO3 v11.0. Use PHPs native "idn_to_ascii($domain, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46)" function directly instead.', E_USER_DEPRECATED); - // Early return in case input is not a string or empty - if (!is_string($value) || empty($value)) { - return (string)$value; - } - // Split on the last "@" since addresses like "foo@bar"@example.org are valid where the only focus - // is an email address - $atPosition = strrpos($value, '@'); - if ($atPosition !== false) { - $domain = substr($value, $atPosition + 1); - $local = substr($value, 0, $atPosition); - $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)HttpUtility::idn_to_ascii($value); - } - /** * Returns a given string with underscores as UpperCamelCase. * Example: Converts blog_example to BlogExample @@ -1720,87 +1642,21 @@ class GeneralUtility * If you are having trouble with proxies when reading URLs you can configure your way out of that with settings within $GLOBALS['TYPO3_CONF_VARS']['HTTP']. * * @param string $url File/URL to read - * @param int $includeHeader Whether the HTTP header should be fetched or not. 0=disable, 1=fetch header+content, 2=fetch header only - deprecated and will be removed in TYPO3 v11. - * @param array $requestHeaders HTTP headers to be used in the request - deprecated and will be removed in TYPO3 v11. - * @param array $report Error code/message and, if $includeHeader is 1, response meta data (HTTP status and content type) - deprecated and will be removed in TYPO3 v11. * @return mixed The content from the resource given as input. FALSE if an error has occurred. */ - public static function getUrl($url, $includeHeader = 0, $requestHeaders = null, &$report = null) + public static function getUrl($url) { - if (func_num_args() > 1) { - trigger_error('Calling GeneralUtility::getUrl() with more than one argument will not be supported anymore in TYPO3 v11.0. Use RequestFactory and PSR-7 Requests and Response objects to evaluate the results in detail. For local files, use file_get_contents directly.', E_USER_DEPRECATED); - } - if (isset($report)) { - $report['error'] = 0; - $report['message'] = ''; - } // Looks like it's an external file, use Guzzle by default if (preg_match('/^(?:http|ftp)s?|s(?:ftp|cp):/', $url)) { $requestFactory = static::makeInstance(RequestFactory::class); - if (is_array($requestHeaders)) { - $configuration = ['headers' => $requestHeaders]; - } else { - $configuration = []; - } - $includeHeader = (int)$includeHeader; - $method = $includeHeader === 2 ? 'HEAD' : 'GET'; try { - if (isset($report)) { - $report['lib'] = 'GuzzleHttp'; - } - $response = $requestFactory->request($url, $method, $configuration); + $response = $requestFactory->request($url); } catch (RequestException $exception) { - if (isset($report)) { - $report['error'] = $exception->getCode() ?: 1518707554; - $report['message'] = $exception->getMessage(); - $report['exception'] = $exception; - } return false; } - $content = ''; - // Add the headers to the output - if ($includeHeader) { - $parsedURL = parse_url($url); - $content = $method . ' ' . ($parsedURL['path'] ?? '/') - . (!empty($parsedURL['query']) ? '?' . $parsedURL['query'] : '') . ' HTTP/1.0' . CRLF - . 'Host: ' . $parsedURL['host'] . CRLF - . 'Connection: close' . CRLF; - if (is_array($requestHeaders)) { - $content .= implode(CRLF, $requestHeaders) . CRLF; - } - foreach ($response->getHeaders() as $headerName => $headerValues) { - $content .= $headerName . ': ' . implode(', ', $headerValues) . CRLF; - } - // Headers are separated from the body with two CRLFs - $content .= CRLF; - } - - $content .= $response->getBody()->getContents(); - - if (isset($report)) { - if ($response->getStatusCode() >= 300 && $response->getStatusCode() < 400) { - $report['http_code'] = $response->getStatusCode(); - $report['content_type'] = $response->getHeaderLine('Content-Type'); - $report['error'] = $response->getStatusCode(); - $report['message'] = $response->getReasonPhrase(); - } elseif (empty($content)) { - $report['error'] = $response->getStatusCode(); - $report['message'] = $response->getReasonPhrase(); - } elseif ($includeHeader) { - // Set only for $includeHeader to work exactly like PHP variant - $report['http_code'] = $response->getStatusCode(); - $report['content_type'] = $response->getHeaderLine('Content-Type'); - } - } + $content = $response->getBody()->getContents(); } else { - if (isset($report)) { - $report['lib'] = 'file'; - } $content = @file_get_contents($url); - if ($content === false && isset($report)) { - $report['error'] = -1; - $report['message'] = 'Couldn\'t get URL: ' . $url; - } } return $content; } @@ -2103,44 +1959,6 @@ class GeneralUtility return $OK; } - /** - * Flushes a directory by first moving to a temporary resource, and then - * triggering the remove process. This way directories can be flushed faster - * to prevent race conditions on concurrent processes accessing the same directory. - * - * @param string $directory The directory to be renamed and flushed - * @param bool $keepOriginalDirectory Whether to only empty the directory and not remove it - * @param bool $flushOpcodeCache Also flush the opcode cache right after renaming the directory. - * @return bool Whether the action was successful - * @deprecated will be removed in TYPO3 v11.0. This is a specific logic needed for the caching framework, and should be implemented where needed directly. - */ - public static function flushDirectory($directory, $keepOriginalDirectory = false, $flushOpcodeCache = false) - { - trigger_error('GeneralUtility::flushDirectory() will be removed in TYPO3 v11.0. This is a specific logic needed for the caching framework, and should be implemented where needed directly.', E_USER_DEPRECATED); - $result = false; - - if (is_link($directory)) { - // Avoid attempting to rename the symlink see #87367 - $directory = realpath($directory); - } - - if (is_dir($directory)) { - $temporaryDirectory = rtrim($directory, '/') . '.' . StringUtility::getUniqueId('remove'); - if (rename($directory, $temporaryDirectory)) { - if ($flushOpcodeCache) { - self::makeInstance(OpcodeCacheService::class)->clearAllActive($directory); - } - if ($keepOriginalDirectory) { - static::mkdir($directory); - } - clearstatcache(); - $result = static::rmdir($temporaryDirectory, true); - } - } - - return $result; - } - /** * Returns an array with the names of folders in a specific path * Will return 'error' (string) if there were an error with reading directory content. @@ -2514,30 +2332,6 @@ class GeneralUtility return $pString ? $parts . '?' . ltrim($pString, '&') : $parts; } - /** - * Takes a full URL, $url, possibly with a querystring and overlays the $getParams arrays values onto the querystring, packs it all together and returns the URL again. - * So basically it adds the parameters in $getParams to an existing URL, $url - * - * @param string $url URL string - * @param array $getParams Array of key/value pairs for get parameters to add/overrule with. Can be multidimensional. - * @return string Output URL with added getParams. - * @deprecated will be removed in TYPO3 v11.0. Use PSR-7 URI objects instead. - */ - public static function linkThisUrl($url, array $getParams = []) - { - trigger_error('GeneralUtility::linkThisUrl() will be removed in TYPO3 v11.0. Use PSR-7 URI objects instead.', E_USER_DEPRECATED); - $parts = parse_url($url); - $getP = []; - if ($parts['query']) { - parse_str($parts['query'], $getP); - } - ArrayUtility::mergeRecursiveWithOverrule($getP, $getParams); - $uP = explode('?', $url); - $params = self::implodeArrayForUrl('', $getP); - $outurl = $uP[0] . ($params ? '?' . substr($params, 1) : ''); - return $outurl; - } - /** * This method is only for testing and should never be used outside tests- * @@ -2921,18 +2715,6 @@ class GeneralUtility return Environment::isCli() || !defined('TYPO3_REQUESTTYPE') || (defined('TYPO3_REQUESTTYPE') && TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_INSTALL); } - /** - * Gets the unixtime as milliseconds. - * - * @return int The unixtime as milliseconds - * @deprecated will be removed in TYPO3 v11.0. Use the native PHP functions round(microtime(true) * 1000) instead. - */ - public static function milliseconds() - { - trigger_error('GeneralUtility::milliseconds() will be removed in TYPO3 v11.0. Use the native PHP functions round(microtime(true) * 1000) instead.', E_USER_DEPRECATED); - return round(microtime(true) * 1000); - } - /************************* * * TYPO3 SPECIFIC FUNCTIONS @@ -3027,22 +2809,6 @@ class GeneralUtility ); } - /** - * Verifies the input filename against the 'fileDenyPattern'. Returns TRUE if OK. - * - * Filenames are not allowed to contain control characters. Therefore we - * always filter on [[:cntrl:]]. - * - * @param string $filename File path to evaluate - * @return bool - * @deprecated will be removed in TYPO3 v11.0. Use the new FileNameValidator API instead. - */ - public static function verifyFilenameAgainstDenyPattern($filename) - { - trigger_error('GeneralUtility::verifyFilenameAgainstDenyPattern() will be removed in TYPO3 v11.0. Use FileNameValidator->isValid($filename) instead.', E_USER_DEPRECATED); - return self::makeInstance(FileNameValidator::class)->isValid((string)$filename); - } - /** * Low level utility function to copy directories and content recursive * @@ -3678,17 +3444,13 @@ class GeneralUtility * * @param string $serviceType Type of service (service key). * @param string $serviceSubType Sub type like file extensions or similar. Defined by the service. - * @param mixed $excludeServiceKeys List of service keys which should be excluded in the search for a service. Array or comma list. + * @param array $excludeServiceKeys List of service keys which should be excluded in the search for a service * @throws \RuntimeException * @return object|string[] The service object or an array with error infos. */ - public static function makeInstanceService($serviceType, $serviceSubType = '', $excludeServiceKeys = []) + public static function makeInstanceService($serviceType, $serviceSubType = '', array $excludeServiceKeys = []) { $error = false; - if (!is_array($excludeServiceKeys)) { - trigger_error('GeneralUtility::makeInstanceService expects the third method argument to be an array instead of a comma-separated string. TYPO3 v11.0 will only support arrays as third argument for $excludeServiceKeys', E_USER_DEPRECATED); - $excludeServiceKeys = self::trimExplode(',', $excludeServiceKeys, true); - } $requestInfo = [ 'requestedServiceType' => $serviceType, 'requestedServiceSubType' => $serviceSubType, @@ -3751,66 +3513,6 @@ class GeneralUtility return $useHtmlEntities ? htmlspecialchars($json) : $json; } - /** - * Set the ApplicationContext - * - * This function is used by the Bootstrap to hand over the application context. It must not be used anywhere else, - * because the context shall never be changed on runtime! - * - * @param \TYPO3\CMS\Core\Core\ApplicationContext $applicationContext - * @throws \RuntimeException if applicationContext is overridden - * @internal This is not a public API method, do not use in own extensions, will probably be removed in TYPO3 v11. - */ - public static function presetApplicationContext(ApplicationContext $applicationContext) - { - if (static::$applicationContext === null) { - static::$applicationContext = $applicationContext; - } else { - throw new \RuntimeException('Trying to override applicationContext which has already been defined!', 1376084316); - } - } - - /** - * For testing purposes only! - * The functional test framework uses this to reset the internal $application context - * variable in between multiple tests before it is re-initialized using presetApplicationContext() - * which otherwise throws an exception if the internal variable is already set. - * - * @internal May be changed or removed any time, will probably be removed in TYPO3 v11. - */ - public static function resetApplicationContext(): void - { - static::$applicationContext = null; - } - - /** - * Get the ApplicationContext - * - * @return \TYPO3\CMS\Core\Core\ApplicationContext - * @deprecated since TYPO3 v10.2, will be removed in TYPO3 v11, use Environment::getContext() instead. - */ - public static function getApplicationContext() - { - trigger_error('GeneralUtility::getApplicationContext() has been superseded by Environment API. This method will be removed in TYPO3 v11. Use Environment::getContext() instead.', E_USER_DEPRECATED); - // Implicitly setting the application context here, but only if it is used, otherwise this does not - // need to be populated. - if (static::$applicationContext === null) { - static::$applicationContext = Environment::getContext(); - } - return static::$applicationContext; - } - - /** - * Check if the current request is running on a CGI server API - * @return bool - * @deprecated will be removed in TYPO3 v11.0. Use Environment::isRunningOnCgiServer() instead. - */ - public static function isRunningOnCgiServerApi() - { - trigger_error('GeneralUtility::isRunningOnCgiServerApi() will be removed in TYPO3 v11.0. Use "Environment::isRunningOnCgiServer()" instead.', E_USER_DEPRECATED); - return Environment::isRunningOnCgiServer(); - } - /** * @return LoggerInterface */ diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-91473-DeprecatedFunctionalityRemoved.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-91473-DeprecatedFunctionalityRemoved.rst index 3a6aaf4732ae..59bccbb54204 100644 --- a/typo3/sysext/core/Documentation/Changelog/master/Breaking-91473-DeprecatedFunctionalityRemoved.rst +++ b/typo3/sysext/core/Documentation/Changelog/master/Breaking-91473-DeprecatedFunctionalityRemoved.rst @@ -34,11 +34,26 @@ The following PHP static class methods that have been previously deprecated for - :php:`\TYPO3\CMS\Backend\Utility\BackendUtility::getViewDomain` - :php:`\TYPO3\CMS\Backend\Utility\BackendUtility::getBackendScript` - :php:`\TYPO3\CMS\Backend\Utility\BackendUtility::TYPO3_copyRightNotice` +- :php:`\TYPO3\CMS\Core\Utility\GeneralUtility::compressIPv6` +- :php:`\TYPO3\CMS\Core\Utility\GeneralUtility::flushDirectory` +- :php:`\TYPO3\CMS\Core\Utility\GeneralUtility::getApplicationContext` +- :php:`\TYPO3\CMS\Core\Utility\GeneralUtility::idnaEncode` +- :php:`\TYPO3\CMS\Core\Utility\GeneralUtility::IPv6Hex2Bin` +- :php:`\TYPO3\CMS\Core\Utility\GeneralUtility::IPv6Bin2Hex` +- :php:`\TYPO3\CMS\Core\Utility\GeneralUtility::isRunningOnCgiServerApi` +- :php:`\TYPO3\CMS\Core\Utility\GeneralUtility::linkThisUrl` +- :php:`\TYPO3\CMS\Core\Utility\GeneralUtility::milliseconds` +- :php:`\TYPO3\CMS\Core\Utility\GeneralUtility::presetApplicationContext` +- :php:`\TYPO3\CMS\Core\Utility\GeneralUtility::resetApplicationContext` +- :php:`\TYPO3\CMS\Core\Utility\GeneralUtility::verifyFilenameAgainstDenyPattern` The following PHP methods have been additionally deprecated and are a no-op now: The following methods changed signature according to previous deprecations in v10 at the end of the argument list: +- :php:`\TYPO3\CMS\Core\Utility\GeneralUtility::getUrl` (arguments 2, 3 and 4 are dropped) +- :php:`\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstanceService` (arguments 3 :php:`$excludeServiceKeys` is now an array) + The following public class properties have been dropped: The following class methods have changed visibility: diff --git a/typo3/sysext/core/Tests/Unit/Utility/GeneralUtilityTest.php b/typo3/sysext/core/Tests/Unit/Utility/GeneralUtilityTest.php index aceb8f3b1ec5..6f9780132309 100644 --- a/typo3/sysext/core/Tests/Unit/Utility/GeneralUtilityTest.php +++ b/typo3/sysext/core/Tests/Unit/Utility/GeneralUtilityTest.php @@ -348,9 +348,9 @@ class GeneralUtilityTest extends UnitTestCase self::assertFalse(GeneralUtility::cmpIPv6($ip, $list)); } - //////////////////////////////////////////////// - // Tests concerning normalizeIPv6 / compressIPv6 - //////////////////////////////////////////////// + ///////////////////////////////// + // Tests concerning normalizeIPv6 + ///////////////////////////////// /** * Data provider for normalizeIPv6ReturnsCorrectlyNormalizedFormat * diff --git a/typo3/sysext/core/Tests/UnitDeprecated/Utility/GeneralUtilityTest.php b/typo3/sysext/core/Tests/UnitDeprecated/Utility/GeneralUtilityTest.php deleted file mode 100644 index 9c56b9f52156..000000000000 --- a/typo3/sysext/core/Tests/UnitDeprecated/Utility/GeneralUtilityTest.php +++ /dev/null @@ -1,343 +0,0 @@ -<?php - -/* - * This file is part of the TYPO3 CMS project. - * - * It is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, either version 2 - * of the License, or any later version. - * - * For the full copyright and license information, please read the - * LICENSE.txt file that was distributed with this source code. - * - * The TYPO3 project - inspiring people to share! - */ - -namespace TYPO3\CMS\Core\Tests\UnitDeprecated\Utility; - -use Prophecy\Argument; -use Psr\Http\Message\ResponseInterface; -use Psr\Http\Message\StreamInterface; -use TYPO3\CMS\Core\Http\RequestFactory; -use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\TestingFramework\Core\Unit\UnitTestCase; - -/** - * Test case - */ -class GeneralUtilityTest extends UnitTestCase -{ - /** - * @var bool Reset singletons created by subject - */ - protected $resetSingletonInstances = true; - - /** - * @test - * @dataProvider idnaEncodeDataProvider - * @param $actual - * @param $expected - */ - public function idnaEncodeConvertsUnicodeCharsToASCIIString($actual, $expected) - { - $result = GeneralUtility::idnaEncode($actual); - self::assertSame($expected, $result); - } - - /** - * Data provider for method idnaEncode in GeneralUtility class. - * IDNA converter has to convert special chars (UTF-8) to ASCII compatible chars. - * - * @returns array - */ - public function idnaEncodeDataProvider() - { - return [ - 'empty string' => [ - '', - '' - ], - 'null value' => [ - null, - '' - ], - 'string with ascii chars' => [ - 'example', - 'example' - ], - 'domain (1) with utf8 chars' => [ - 'dömäin.example', - 'xn--dmin-moa0i.example' - ], - 'domain (2) with utf8 chars' => [ - 'äaaa.example', - 'xn--aaa-pla.example' - ], - 'domain (3) with utf8 chars' => [ - 'déjà .vu.example', - 'xn--dj-kia8a.vu.example' - ], - 'domain (4) with utf8 chars' => [ - 'foo.âbcdéf.example', - 'foo.xn--bcdf-9na9b.example' - ], - 'domain with utf8 char (german umlaut)' => [ - 'exömple.com', - 'xn--exmple-xxa.com' - ], - 'email with utf8 char (german umlaut)' => [ - 'joe.doe@dömäin.de', - 'joe.doe@xn--dmin-moa0i.de' - ] - ]; - } - - /** - * @return array - */ - public function deniedFilesWithoutDenyPatternDataProvider(): array - { - return [ - 'Nul character in file' => ['image' . "\0" . '.gif'], - 'Nul character in file with .php' => ['image.php' . "\0" . '.gif'], - 'Nul character and UTF-8 in file' => ['СÑылка' . "\0" . '.gif'], - 'Nul character and Latin-1 in file' => ['ÉÃØ' . "\0" . '.gif'], - ]; - } - - /** - * Tests whether verifyFilenameAgainstDenyPattern detects files with nul character without file deny pattern. - * - * @param string $deniedFile - * @test - * @dataProvider deniedFilesWithoutDenyPatternDataProvider - */ - public function verifyNulCharacterFilesAgainstPatternWithoutFileDenyPattern(string $deniedFile) - { - $GLOBALS['TYPO3_CONF_VARS']['BE']['fileDenyPattern'] = ''; - self::assertFalse(GeneralUtility::verifyFilenameAgainstDenyPattern($deniedFile)); - } - - /** - * @return array - */ - public function deniedFilesWithDefaultDenyPatternDataProvider(): array - { - $data = [ - 'Nul character in file' => ['image' . "\0", '.gif'], - 'Nul character in file with .php' => ['image.php' . "\0", '.gif'], - 'Nul character and UTF-8 in file' => ['СÑылка' . "\0", '.gif'], - 'Nul character and Latin-1 in file' => ['ÉÃØ' . "\0", '.gif'], - 'Lower umlaut .php file' => ['üWithFile', '.php'], - 'Upper umlaut .php file' => ['fileWithÃœ', '.php'], - 'invalid UTF-8-sequence' => ["\xc0" . 'file', '.php'], - 'Could be overlong NUL in some UTF-8 implementations, invalid in RFC3629' => ["\xc0\x80" . 'file', '.php'], - 'Regular .php file' => ['file' , '.php'], - 'Regular .php3 file' => ['file', '.php3'], - 'Regular .php5 file' => ['file', '.php5'], - 'Regular .php7 file' => ['file', '.php7'], - 'Regular .phpsh file' => ['file', '.phpsh'], - 'Regular .phtml file' => ['file', '.phtml'], - 'Regular .pht file' => ['file', '.pht'], - 'Regular .phar file' => ['file', '.phar'], - 'Regular .shtml file' => ['file', '.shtml'], - 'Regular .cgi file' => ['file', '.cgi'], - 'Regular .pl file' => ['file', '.pl'], - 'Wrapped .php file ' => ['file', '.php.txt'], - 'Wrapped .php3 file' => ['file', '.php3.txt'], - 'Wrapped .php5 file' => ['file', '.php5.txt'], - 'Wrapped .php7 file' => ['file', '.php7.txt'], - 'Wrapped .phpsh file' => ['file', '.phpsh.txt'], - 'Wrapped .phtml file' => ['file', '.phtml.txt'], - 'Wrapped .pht file' => ['file', '.pht.txt'], - 'Wrapped .phar file' => ['file', '.phar.txt'], - 'Wrapped .shtml file' => ['file', '.shtml.txt'], - 'Wrapped .cgi file' => ['file', '.cgi.txt'], - // allowed "Wrapped .pl file" in order to allow language specific files containing ".pl." - '.htaccess file' => ['', '.htaccess'], - ]; - - // Mixing with regular utf-8 - $utf8Characters = 'СÑылка'; - foreach ($data as $key => $value) { - if ($value[0] === '') { - continue; - } - $data[$key . ' with UTF-8 characters prepended'] = [$utf8Characters . $value[0], $value[1]]; - $data[$key . ' with UTF-8 characters appended'] = [$value[0] . $utf8Characters, $value[1]]; - } - - // combine to single value - $data = array_map( - function (array $values): array { - return [implode('', $values)]; - }, - $data - ); - - // Encoding with UTF-16 - foreach ($data as $key => $value) { - $data[$key . ' encoded with UTF-16'] = [mb_convert_encoding($value[0], 'UTF-16')]; - } - - return $data; - } - - /** - * Tests whether verifyFilenameAgainstDenyPattern detects denied files. - * - * @param string $deniedFile - * @test - * @dataProvider deniedFilesWithDefaultDenyPatternDataProvider - */ - public function verifyFilenameAgainstDenyPatternDetectsNotAllowedFiles($deniedFile) - { - self::assertFalse(GeneralUtility::verifyFilenameAgainstDenyPattern($deniedFile)); - } - - /** - * @return array - */ - public function allowedFilesDataProvider(): array - { - return [ - 'Regular .gif file' => ['image.gif'], - 'Regular uppercase .gif file' => ['IMAGE.gif'], - 'UTF-8 .gif file' => ['СÑылка.gif'], - 'Lower umlaut .jpg file' => ['üWithFile.jpg'], - 'Upper umlaut .png file' => ['fileWithÃœ.png'], - 'Latin-1 .gif file' => ['ÉÃØ.gif'], - 'Wrapped .pl file' => ['file.pl.txt'], - ]; - } - - /** - * Tests whether verifyFilenameAgainstDenyPattern accepts allowed files. - * - * @param string $allowedFile - * @test - * @dataProvider allowedFilesDataProvider - */ - public function verifyFilenameAgainstDenyPatternAcceptAllowedFiles(string $allowedFile) - { - self::assertTrue(GeneralUtility::verifyFilenameAgainstDenyPattern($allowedFile)); - } - - public function splitHeaderLinesDataProvider(): array - { - return [ - 'multi-line headers' => [ - ['Content-Type' => 'multipart/form-data; boundary=something', 'Content-Language' => 'de-DE, en-CA'], - ['Content-Type' => 'multipart/form-data; boundary=something', 'Content-Language' => 'de-DE, en-CA'], - ] - ]; - } - - /** - * @test - * @dataProvider splitHeaderLinesDataProvider - * @param array $headers - * @param array $expectedHeaders - */ - public function splitHeaderLines(array $headers, array $expectedHeaders): void - { - $stream = $this->prophesize(StreamInterface::class); - $response = $this->prophesize(ResponseInterface::class); - $response->getBody()->willReturn($stream); - $requestFactory = $this->prophesize(RequestFactory::class); - $requestFactory->request(Argument::cetera())->willReturn($response); - - GeneralUtility::addInstance(RequestFactory::class, $requestFactory->reveal()); - GeneralUtility::getUrl('http://example.com', 0, $headers); - - $requestFactory->request(Argument::any(), Argument::any(), ['headers' => $expectedHeaders])->shouldHaveBeenCalled(); - } - - /** - * Data provider for IPv6Hex2BinCorrect - * - * @return array Data sets - */ - public static function IPv6Hex2BinDataProviderCorrect() - { - return [ - 'empty 1' => ['::', str_pad('', 16, "\x00")], - 'empty 2, already normalized' => ['0000:0000:0000:0000:0000:0000:0000:0000', str_pad('', 16, "\x00")], - 'already normalized' => ['0102:0304:0000:0000:0000:0000:0506:0078', "\x01\x02\x03\x04" . str_pad('', 8, "\x00") . "\x05\x06\x00\x78"], - 'expansion in middle 1' => ['1::2', "\x00\x01" . str_pad('', 12, "\x00") . "\x00\x02"], - 'expansion in middle 2' => ['beef::fefa', "\xbe\xef" . str_pad('', 12, "\x00") . "\xfe\xfa"], - ]; - } - - /** - * @test - * @dataProvider IPv6Hex2BinDataProviderCorrect - */ - public function IPv6Hex2BinCorrectlyConvertsAddresses($hex, $binary) - { - self::assertTrue(GeneralUtility::IPv6Hex2Bin($hex) === $binary); - } - - /** - * Data provider for IPv6Bin2HexCorrect - * - * @return array Data sets - */ - public static function IPv6Bin2HexDataProviderCorrect() - { - return [ - 'empty' => [str_pad('', 16, "\x00"), '::'], - 'non-empty front' => ["\x01" . str_pad('', 15, "\x00"), '100::'], - 'non-empty back' => [str_pad('', 15, "\x00") . "\x01", '::1'], - 'normalized' => ["\x01\x02\x03\x04" . str_pad('', 8, "\x00") . "\x05\x06\x00\x78", '102:304::506:78'], - 'expansion in middle 1' => ["\x00\x01" . str_pad('', 12, "\x00") . "\x00\x02", '1::2'], - 'expansion in middle 2' => ["\xbe\xef" . str_pad('', 12, "\x00") . "\xfe\xfa", 'beef::fefa'], - ]; - } - - /** - * @test - * @dataProvider IPv6Bin2HexDataProviderCorrect - */ - public function IPv6Bin2HexCorrectlyConvertsAddresses($binary, $hex) - { - self::assertEquals(GeneralUtility::IPv6Bin2Hex($binary), $hex); - } - - /** - * Data provider for normalizeIPv6ReturnsCorrectlyNormalizedFormat - * - * @return array Data sets - */ - public static function normalizeCompressIPv6DataProviderCorrect() - { - return [ - 'empty' => ['::', '0000:0000:0000:0000:0000:0000:0000:0000'], - 'localhost' => ['::1', '0000:0000:0000:0000:0000:0000:0000:0001'], - 'expansion in middle 1' => ['1::2', '0001:0000:0000:0000:0000:0000:0000:0002'], - 'expansion in middle 2' => ['1:2::3', '0001:0002:0000:0000:0000:0000:0000:0003'], - 'expansion in middle 3' => ['1::2:3', '0001:0000:0000:0000:0000:0000:0002:0003'], - 'expansion in middle 4' => ['1:2::3:4:5', '0001:0002:0000:0000:0000:0003:0004:0005'] - ]; - } - - /** - * @test - * @dataProvider normalizeCompressIPv6DataProviderCorrect - */ - public function compressIPv6CorrectlyCompressesAddresses($compressed, $normalized) - { - self::assertEquals($compressed, GeneralUtility::compressIPv6($normalized)); - } - - /** - * @test - */ - public function compressIPv6CorrectlyCompressesAddressWithSomeAddressOnRightSide() - { - if (strtolower(PHP_OS) === 'darwin') { - self::markTestSkipped('This test does not work on OSX / Darwin OS.'); - } - self::assertEquals('::f0f', GeneralUtility::compressIPv6('0000:0000:0000:0000:0000:0000:0000:0f0f')); - } -} diff --git a/typo3/sysext/core/composer.json b/typo3/sysext/core/composer.json index 40e50721276e..a7b27d22caa3 100644 --- a/typo3/sysext/core/composer.json +++ b/typo3/sysext/core/composer.json @@ -69,7 +69,7 @@ "phpspec/prophecy": "^1.7.5", "phpstan/phpstan": "^0.12.13", "typo3/cms-styleguide": "~10.0.2", - "typo3/testing-framework": "^6.3.0" + "typo3/testing-framework": "^6.3.1" }, "suggest": { "ext-fileinfo": "Used for proper file type detection in the file abstraction layer", diff --git a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodArgumentDroppedStaticMatcher.php b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodArgumentDroppedStaticMatcher.php index 5fb9ddb34b32..f7668349a6da 100644 --- a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodArgumentDroppedStaticMatcher.php +++ b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodArgumentDroppedStaticMatcher.php @@ -70,6 +70,7 @@ return [ 'maximumNumberOfArguments' => 1, 'restFiles' => [ 'Deprecation-90956-AlternativeFetchMethodsAndReportsForGeneralUtilitygetUrl.rst', + 'Breaking-91473-DeprecatedFunctionalityRemoved.rst' ], ], ]; diff --git a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallStaticMatcher.php b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallStaticMatcher.php index e0311ab70574..318b2fceaf26 100644 --- a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallStaticMatcher.php +++ b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallStaticMatcher.php @@ -860,6 +860,7 @@ return [ 'maximumNumberOfArguments' => 1, 'restFiles' => [ 'Deprecation-87894-GeneralUtilityidnaEncode.rst', + 'Breaking-91473-DeprecatedFunctionalityRemoved.rst' ], ], 'TYPO3\CMS\Core\Context\LanguageAspectFactory::createFromTypoScript' => [ @@ -924,7 +925,8 @@ return [ 'numberOfMandatoryArguments' => 0, 'maximumNumberOfArguments' => 0, 'restFiles' => [ - 'Deprecation-89631-UseEnvironmentAPIToFetchApplicationContext.rst' + 'Deprecation-89631-UseEnvironmentAPIToFetchApplicationContext.rst', + 'Breaking-91473-DeprecatedFunctionalityRemoved.rst' ], ], 'TYPO3\CMS\Backend\Utility\BackendUtility::getRawPagesTSconfig' => [ @@ -955,55 +957,63 @@ return [ 'maximumNumberOfArguments' => 0, 'restFiles' => [ 'Deprecation-90800-GeneralUtilityisRunningOnCgiServerApi.rst', + 'Breaking-91473-DeprecatedFunctionalityRemoved.rst' ], ], 'TYPO3\CMS\Core\Utility\GeneralUtility::verifyFilenameAgainstDenyPattern' => [ 'numberOfMandatoryArguments' => 1, 'maximumNumberOfArguments' => 1, 'restFiles' => [ - 'Deprecation-90147-UnifiedFileNameValidator.rst' + 'Deprecation-90147-UnifiedFileNameValidator.rst', + 'Breaking-91473-DeprecatedFunctionalityRemoved.rst' ], ], 'TYPO3\CMS\Core\Utility\GeneralUtility::IPv6Hex2Bin' => [ 'numberOfMandatoryArguments' => 1, 'maximumNumberOfArguments' => 1, 'restFiles' => [ - 'Deprecation-91001-VariousMethodsWithinGeneralUtility.rst' + 'Deprecation-91001-VariousMethodsWithinGeneralUtility.rst', + 'Breaking-91473-DeprecatedFunctionalityRemoved.rst' ], ], 'TYPO3\CMS\Core\Utility\GeneralUtility::IPv6Bin2Hex' => [ 'numberOfMandatoryArguments' => 1, 'maximumNumberOfArguments' => 1, 'restFiles' => [ - 'Deprecation-91001-VariousMethodsWithinGeneralUtility.rst' + 'Deprecation-91001-VariousMethodsWithinGeneralUtility.rst', + 'Breaking-91473-DeprecatedFunctionalityRemoved.rst' ], ], 'TYPO3\CMS\Core\Utility\GeneralUtility::compressIPv6' => [ 'numberOfMandatoryArguments' => 1, 'maximumNumberOfArguments' => 1, 'restFiles' => [ - 'Deprecation-91001-VariousMethodsWithinGeneralUtility.rst' + 'Deprecation-91001-VariousMethodsWithinGeneralUtility.rst', + 'Breaking-91473-DeprecatedFunctionalityRemoved.rst' ], ], 'TYPO3\CMS\Core\Utility\GeneralUtility::milliseconds' => [ 'numberOfMandatoryArguments' => 0, 'maximumNumberOfArguments' => 0, 'restFiles' => [ - 'Deprecation-91001-VariousMethodsWithinGeneralUtility.rst' + 'Deprecation-91001-VariousMethodsWithinGeneralUtility.rst', + 'Breaking-91473-DeprecatedFunctionalityRemoved.rst' ], ], 'TYPO3\CMS\Core\Utility\GeneralUtility::linkThisUrl' => [ 'numberOfMandatoryArguments' => 1, 'maximumNumberOfArguments' => 2, 'restFiles' => [ - 'Deprecation-91001-VariousMethodsWithinGeneralUtility.rst' + 'Deprecation-91001-VariousMethodsWithinGeneralUtility.rst', + 'Breaking-91473-DeprecatedFunctionalityRemoved.rst' ], ], 'TYPO3\CMS\Core\Utility\GeneralUtility::flushDirectory' => [ 'numberOfMandatoryArguments' => 1, 'maximumNumberOfArguments' => 3, 'restFiles' => [ - 'Deprecation-91001-VariousMethodsWithinGeneralUtility.rst' + 'Deprecation-91001-VariousMethodsWithinGeneralUtility.rst', + 'Breaking-91473-DeprecatedFunctionalityRemoved.rst' ], ], ]; -- GitLab