diff --git a/composer.json b/composer.json index 57fe608720386360abfa3539671e27c1dd55a224..7152b6dee0085f67b435f397217855745fc40591 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 084063d0ed27a877371189ba5888811cc697bb39..17cac2f410b98f2f2f64f06884dada99667ef82b 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 728dc0e440a0d7c74720920b4c5ff913a5ccf3a3..4d0a3e3360115f3e072207e145446558fc9a623d 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 3a6aaf4732ae78ed73f295bac2bff01a8c54089e..59bccbb542044362243d906105b7641c7db126d6 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 aceb8f3b1ec592de011ea9b9336ca657750aeef5..6f978013230932d0f06d5485b271aee027f57fdb 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 9c56b9f52156c52a2fbe26a878b793b462564d8e..0000000000000000000000000000000000000000 --- 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 40e50721276e0e0ed1f393dc668d3ef9ef226b83..a7b27d22caa3317c0b97a53e4cccb88f17d107ba 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 5fb9ddb34b326225154eb04b99fb69058863a5d3..f7668349a6da455823340a7e49ac6941a94b0569 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 e0311ab7057492cddb9a926ee0acb0322d9b4ab7..318b2fceaf269097aa85df1e58dda1841a90995f 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' ], ], ];