diff --git a/Build/phpstan.php7config.php b/Build/phpstan.php7config.php index 6f2d88f940ea30d02663d5100bca992d9cac3fd0..b42a888bc9bbe350a58dba9e3031761bc442937b 100644 --- a/Build/phpstan.php7config.php +++ b/Build/phpstan.php7config.php @@ -7,11 +7,6 @@ $config = []; if (PHP_MAJOR_VERSION === 7) { $config['parameters']['ignoreErrors'] = [ '#Class GdImage not found.#', - [ - 'message' => '#^Parameter \\#[1-4]{1} \\$[a-z]* of function [a-z_]* expects resource, resource\\|XmlParser given\\.$#', - 'path' => '%currentWorkingDirectory%/typo3/sysext/extensionmanager/Classes/Utility/Parser/ExtensionXmlPushParser.php', - 'count' => 9, - ], [ 'message' => '#^Parameter \\#1 \\$sem_identifier of function sem_release expects resource, resource\\|SysvSemaphore given\\.$#', 'path' => '%currentWorkingDirectory%/typo3/sysext/core/Classes/Locking/SemaphoreLockStrategy.php', @@ -71,7 +66,32 @@ if (PHP_MAJOR_VERSION === 7) { 'message' => '#^Parameter \\#2 \\$col of function imagecolortransparent expects int, int\\|false given\\.$#', 'path' => '%currentWorkingDirectory%/typo3/sysext/frontend/Classes/Imaging/GifBuilder.php', 'count' => 1 - ] + ], + [ + 'message' => '#^Parameter \\#1 \\$parser of function xml_parse expects resource, XMLParser given\\.$#', + 'path' => '%currentWorkingDirectory%/typo3/sysext/extensionmanager/Classes/Utility/Parser/ExtensionXmlPushParser.php', + 'count' => 1 + ], + [ + 'message' => '#^Parameter \\#1 \\$parser of function xml_parser_free expects resource, XMLParser given\\.$#', + 'path' => '%currentWorkingDirectory%/typo3/sysext/extensionmanager/Classes/Utility/Parser/ExtensionXmlPushParser.php', + 'count' => 1 + ], + [ + 'message' => '#^Parameter \\#1 \\$parser of function xml_parser_set_option expects resource, XMLParser given\\.$#', + 'path' => '%currentWorkingDirectory%/typo3/sysext/extensionmanager/Classes/Utility/Parser/ExtensionXmlPushParser.php', + 'count' => 3 + ], + [ + 'message' => '#^Parameter \\#1 \\$parser of function xml_set_character_data_handler expects resource, XMLParser given\\.$#', + 'path' => '%currentWorkingDirectory%/typo3/sysext/extensionmanager/Classes/Utility/Parser/ExtensionXmlPushParser.php', + 'count' => 1 + ], + [ + 'message' => '#^Parameter \\#1 \\$parser of function xml_set_element_handler expects resource, XMLParser given\\.$#', + 'path' => '%currentWorkingDirectory%/typo3/sysext/extensionmanager/Classes/Utility/Parser/ExtensionXmlPushParser.php', + 'count' => 1 + ], ]; } diff --git a/Build/phpstan.php8config.php b/Build/phpstan.php8config.php index 1ab39fda68ebde4d8f3c048977c53fdc1e47c76d..54d64fc20fd83eb1636ee4ccf3da35ba9c38f566 100644 --- a/Build/phpstan.php8config.php +++ b/Build/phpstan.php8config.php @@ -41,11 +41,6 @@ if (PHP_MAJOR_VERSION === 8) { 'path' => '%currentWorkingDirectory%/', 'count' => 6, ], - [ - 'message' => '#^Parameter \\#[1-4]{1} \\$[a-z]* of function [a-z_]* expects XmlParser, resource\\|XmlParser given\\.$#', - 'path' => '%currentWorkingDirectory%/typo3/sysext/extensionmanager/Classes/Utility/Parser/ExtensionXmlPushParser.php', - 'count' => 9, - ], [ 'message' => '#^Parameter \\#1 \\$semaphore of function sem_release expects SysvSemaphore, resource\\|SysvSemaphore given\\.$#', 'path' => '%currentWorkingDirectory%/typo3/sysext/core/Classes/Locking/SemaphoreLockStrategy.php', @@ -60,7 +55,32 @@ if (PHP_MAJOR_VERSION === 8) { 'message' => '#^Parameter \\#2 \\$color of function imagecolortransparent expects int\\|null, int\\|false given\\.$#', 'path' => '%currentWorkingDirectory%/typo3/sysext/frontend/Classes/Imaging/GifBuilder.php', 'count' => 1 - ] + ], + [ + 'message' => '#^Parameter \\#1 \\$parser of function xml_parse expects XMLParser, resource given\\.$#', + 'path' => '%currentWorkingDirectory%/typo3/sysext/extensionmanager/Classes/Utility/Parser/ExtensionXmlPushParser.php', + 'count' => 1 + ], + [ + 'message' => '#^Parameter \\#1 \\$parser of function xml_parser_free expects XMLParser, resource given\\.$#', + 'path' => '%currentWorkingDirectory%/typo3/sysext/extensionmanager/Classes/Utility/Parser/ExtensionXmlPushParser.php', + 'count' => 1 + ], + [ + 'message' => '#^Parameter \\#1 \\$parser of function xml_parser_set_option expects XMLParser, resource given\\.$#', + 'path' => '%currentWorkingDirectory%/typo3/sysext/extensionmanager/Classes/Utility/Parser/ExtensionXmlPushParser.php', + 'count' => 3 + ], + [ + 'message' => '#^Parameter \\#1 \\$parser of function xml_set_character_data_handler expects XMLParser, resource given\\.$#', + 'path' => '%currentWorkingDirectory%/typo3/sysext/extensionmanager/Classes/Utility/Parser/ExtensionXmlPushParser.php', + 'count' => 1 + ], + [ + 'message' => '#^Parameter \\#1 \\$parser of function xml_set_element_handler expects XMLParser, resource given\\.$#', + 'path' => '%currentWorkingDirectory%/typo3/sysext/extensionmanager/Classes/Utility/Parser/ExtensionXmlPushParser.php', + 'count' => 1 + ], ]; } diff --git a/composer.lock b/composer.lock index 782cc312502b9cee131ca8284983bc8d1278848e..69204e94a56e6e696296b5a31ce692808d8de428 100644 --- a/composer.lock +++ b/composer.lock @@ -5908,16 +5908,16 @@ }, { "name": "phpstan/phpstan", - "version": "0.12.64", + "version": "0.12.84", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "23eb1cb7ae125f45f1d0e48051bcf67a9a9b08aa" + "reference": "9c43f15da8798c8f30a4b099e6a94530a558cfd5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/23eb1cb7ae125f45f1d0e48051bcf67a9a9b08aa", - "reference": "23eb1cb7ae125f45f1d0e48051bcf67a9a9b08aa", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/9c43f15da8798c8f30a4b099e6a94530a558cfd5", + "reference": "9c43f15da8798c8f30a4b099e6a94530a558cfd5", "shasum": "" }, "require": { @@ -5948,7 +5948,7 @@ "description": "PHPStan - PHP Static Analysis Tool", "support": { "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/0.12.64" + "source": "https://github.com/phpstan/phpstan/tree/0.12.84" }, "funding": [ { @@ -5964,7 +5964,7 @@ "type": "tidelift" } ], - "time": "2020-12-21T11:59:02+00:00" + "time": "2021-04-19T17:10:54+00:00" }, { "name": "phpunit/php-code-coverage", diff --git a/phpstan.neon b/phpstan.neon index 7c3ddfd027bc580a583f710a7eb02b1e0446dfac..1b30a45210d0b5ba31596e7f500548a365248102 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -47,7 +47,7 @@ parameters: message: '#Parameter \$event of method [\w\\]+::\w+\(\) has invalid typehint type Composer\\Script\\Event\.#' path: %currentWorkingDirectory%/typo3/sysext/*/Classes/Composer/* - - message: "#^Access to undefined constant TYPO3\\\\CMS\\\\Core\\\\Type\\\\Enumeration\\:\\:__default\\.$#" + message: "#^Access to undefined constant static\\(TYPO3\\\\CMS\\\\Core\\\\Type\\\\Enumeration\\)\\:\\:__default\\.$#" count: 1 path: typo3/sysext/core/Classes/Type/Enumeration.php - @@ -178,10 +178,6 @@ parameters: message: "#^Parameter \\#1 \\$name of function setcookie expects string, string\\|false given\\.$#" count: 1 path: typo3/sysext/install/Classes/Service/SessionService.php - - - message: "#^Unable to resolve the template type T in call to method static method Doctrine\\\\DBAL\\\\DriverManager\\:\\:getConnection\\(\\)$#" - count: 4 - path: typo3/sysext/install/Classes/Controller/InstallerController.php - message: "#^Parameter \\#1 \\$params of static method Doctrine\\\\DBAL\\\\DriverManager\\:\\:getConnection\\(\\) expects array\\(\\?'wrapperClass' \\=\\> class\\-string\\<Doctrine\\\\DBAL\\\\Connection\\>\\), array\\<string, string\\>&nonEmpty given\\.$#" count: 1 @@ -238,14 +234,6 @@ parameters: message: "#^Parameter \\#1 \\$address of method TYPO3\\\\CMS\\\\Core\\\\Mail\\\\Rfc822AddressesParser\\:\\:_splitAddresses\\(\\) expects string, string\\|true given\\.$#" count: 1 path: typo3/sysext/core/Classes/Mail/Rfc822AddressesParser.php - - - message: "#^Parameter \\#1 \\$(exception_handler|callback) of function set_exception_handler expects \\(callable\\(Throwable\\)\\: void\\)\\|null, array\\(\\$this\\(TYPO3\\\\CMS\\\\Core\\\\Error\\\\ProductionExceptionHandler\\), 'handleException'\\) given\\.$#" - count: 1 - path: typo3/sysext/core/Classes/Error/ProductionExceptionHandler.php - - - message: "#^Parameter \\#1 \\$(exception_handler|callback) of function set_exception_handler expects \\(callable\\(Throwable\\)\\: void\\)\\|null, array\\(\\$this\\(TYPO3\\\\CMS\\\\Core\\\\Error\\\\DebugExceptionHandler\\), 'handleException'\\) given\\.$#" - count: 1 - path: typo3/sysext/core/Classes/Error/DebugExceptionHandler.php - message: "#^Parameter \\#2 \\$package of method TYPO3\\\\CMS\\\\Core\\\\DependencyInjection\\\\ServiceProviderRegistry\\:\\:create\\(\\) expects TYPO3\\\\CMS\\\\Core\\\\Package\\\\Package\\|null, TYPO3\\\\CMS\\\\Core\\\\Package\\\\PackageInterface given\\.$#" count: 1 @@ -254,10 +242,6 @@ parameters: message: "#^Parameter \\#1 \\$(name|function) of class ReflectionFunction constructor expects Closure\\|string, callable\\(\\)\\: mixed given\\.$#" count: 1 path: typo3/sysext/core/Classes/DependencyInjection/ServiceProviderCompilationPass.php - - - message: "#^Unable to resolve the template type T in call to method static method Doctrine\\\\DBAL\\\\DriverManager\\:\\:getConnection\\(\\)$#" - count: 1 - path: typo3/sysext/core/Classes/Database/ConnectionPool.php - message: "#^Parameter \\#1 \\$manifest of method TYPO3\\\\CMS\\\\Core\\\\Core\\\\ClassLoadingInformationGenerator\\:\\:getAutoloadSectionFromManifest\\(\\) expects stdClass, object given\\.$#" count: 2 diff --git a/typo3/sysext/backend/Classes/Controller/FileStorage/TreeController.php b/typo3/sysext/backend/Classes/Controller/FileStorage/TreeController.php index 83b5e55f5fe1044e2f0131d50ad50efad340efe3..9b56099531ba70350082463bd177104786ed72ea 100644 --- a/typo3/sysext/backend/Classes/Controller/FileStorage/TreeController.php +++ b/typo3/sysext/backend/Classes/Controller/FileStorage/TreeController.php @@ -135,9 +135,10 @@ class TreeController return false; }); $positionFound = false; - $siblingsBeforeInSameDepth = array_filter($siblings, function ($itemInArray) use ($stateIdentifier, &$positionFound) { + $siblingsBeforeInSameDepth = array_filter($siblings, function ($itemInArray) use ($stateIdentifier, &$positionFound): bool { if ($itemInArray['stateIdentifier'] === $stateIdentifier) { $positionFound = true; + return false; } return !$positionFound; }); diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexPrepare.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexPrepare.php index b63e01090d5e4b31240ea309e5dad2e80bd0595b..142d8161ee8b344552a5d784676f836f24d4bebd 100644 --- a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexPrepare.php +++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexPrepare.php @@ -74,6 +74,7 @@ class TcaFlexPrepare implements FormDataProviderInterface $flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class); $dataStructureArray = ['sheets' => ['sDEF' => []]]; + $dataStructureIdentifier = null; try { $dataStructureIdentifier = $flexFormTools->getDataStructureIdentifier( diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSelectItems.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSelectItems.php index efdf99ea50f104b2a7b756146768a2909423930c..af45734fc0088bfb33e0d9bbcd70cef4f4f2eaa7 100644 --- a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSelectItems.php +++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSelectItems.php @@ -295,7 +295,7 @@ class TcaSelectItems extends AbstractItemProvider implements FormDataProviderInt $items, function ($item1, $item2) use ($direction) { if ($direction === 'desc') { - return strcasecmp($item1[0], $item2[0]) <= 0; + return (strcasecmp($item1[0], $item2[0]) <= 0) ? 1 : 0; } return strcasecmp($item1[0], $item2[0]); } @@ -307,7 +307,7 @@ class TcaSelectItems extends AbstractItemProvider implements FormDataProviderInt $items, function ($item1, $item2) use ($direction) { if ($direction === 'desc') { - return strcasecmp($item1[1], $item2[1]) <= 0; + return (strcasecmp($item1[1], $item2[1]) <= 0) ? 1 : 0; } return strcasecmp($item1[1], $item2[1]); } diff --git a/typo3/sysext/backend/Classes/Utility/BackendUtility.php b/typo3/sysext/backend/Classes/Utility/BackendUtility.php index 42f5215a6424d20ceee967d48a628ba510a83f70..35b401fb5e1f7f2e99ec8942af913daa1bb47e30 100644 --- a/typo3/sysext/backend/Classes/Utility/BackendUtility.php +++ b/typo3/sysext/backend/Classes/Utility/BackendUtility.php @@ -3204,14 +3204,14 @@ class BackendUtility ->fetchColumn(0); } - if ($count && $msg) { + if ($count !== null && $msg !== '') { return sprintf($msg, $count); } - if ($count) { - return $msg ? sprintf($msg, $count) : $count; + if ($count !== null) { + return (string)$count; } - return $msg ? '' : 0; + return $msg !== '' ? '' : '0'; } /******************************************* diff --git a/typo3/sysext/core/Classes/DataHandling/DataHandler.php b/typo3/sysext/core/Classes/DataHandling/DataHandler.php index 8bf3f22867b5860aed022a4f948926d8441b1979..23ac3a7d6da235245fac85c890d825b04a29e613 100644 --- a/typo3/sysext/core/Classes/DataHandling/DataHandler.php +++ b/typo3/sysext/core/Classes/DataHandling/DataHandler.php @@ -4592,7 +4592,10 @@ class DataHandler implements LoggerAwareInterface continue; } $item['id'] = $this->localize($item['table'], $item['id'], $language); - $item['id'] = $this->overlayAutoVersionId($item['table'], $item['id']); + + if (is_int($item['id'])) { + $item['id'] = $this->overlayAutoVersionId($item['table'], $item['id']); + } $dbAnalysisCurrent->itemArray[] = $item; } } elseif (!empty($ids)) { @@ -4605,7 +4608,9 @@ class DataHandler implements LoggerAwareInterface continue; } $item['id'] = $this->localize($item['table'], $item['id'], $language); - $item['id'] = $this->overlayAutoVersionId($item['table'], $item['id']); + if (is_int($item['id'])) { + $item['id'] = $this->overlayAutoVersionId($item['table'], $item['id']); + } $dbAnalysisCurrent->itemArray[] = $item; } } diff --git a/typo3/sysext/core/Classes/Html/RteHtmlParser.php b/typo3/sysext/core/Classes/Html/RteHtmlParser.php index 21e13a3b4c94430279f26e2f49747e9fe153a834..1e1694b1c455c49ce2029e63726854c8c250a2ad 100644 --- a/typo3/sysext/core/Classes/Html/RteHtmlParser.php +++ b/typo3/sysext/core/Classes/Html/RteHtmlParser.php @@ -398,14 +398,16 @@ class RteHtmlParser extends HtmlParser implements LoggerAwareInterface } else { // NON-block: if (trim($blockSplit[$k]) !== '') { - $blockSplit[$k] = str_replace('<hr/>', '<hr />', $blockSplit[$k]); + $string = $blockSplit[$k]; + $string = str_replace('<hr/>', '<hr />', $string); // Remove linebreaks preceding hr tags - $blockSplit[$k] = preg_replace('/[' . LF . ']+<(hr)(\\s[^>\\/]*)?[[:space:]]*\\/?>/', '<$1$2/>', $blockSplit[$k]); + $string = preg_replace('/[' . LF . ']+<(hr)(\\s[^>\\/]*)?[[:space:]]*\\/?>/', '<$1$2/>', $string) ?? ''; // Remove linebreaks following hr tags - $blockSplit[$k] = preg_replace('/<(hr)(\\s[^>\\/]*)?[[:space:]]*\\/?>[' . LF . ']+/', '<$1$2/>', $blockSplit[$k]); + $string = preg_replace('/<(hr)(\\s[^>\\/]*)?[[:space:]]*\\/?>[' . LF . ']+/', '<$1$2/>', $string) ?? ''; // Replace other linebreaks with space - $blockSplit[$k] = preg_replace('/[' . LF . ']+/', ' ', $blockSplit[$k]); - $blockSplit[$k] = $this->divideIntoLines($blockSplit[$k]); + $string = preg_replace('/[' . LF . ']+/', ' ', $string); + /** @var string $string */ + $blockSplit[$k] = $this->divideIntoLines($string); } else { unset($blockSplit[$k]); } diff --git a/typo3/sysext/core/Classes/Http/Stream.php b/typo3/sysext/core/Classes/Http/Stream.php index 093d964428c941e207db884f5c8134fc926accf0..849e78ccb82b71b02293a8088f4f5fee778aa85f 100644 --- a/typo3/sysext/core/Classes/Http/Stream.php +++ b/typo3/sysext/core/Classes/Http/Stream.php @@ -344,8 +344,9 @@ class Stream implements StreamInterface { $error = null; if (!is_resource($resource) && is_string($resource)) { - set_error_handler(function ($e) use (&$error) { + set_error_handler(function ($e) use (&$error): bool { $error = $e; + return true; }, E_WARNING); $resource = fopen($resource, $mode); restore_error_handler(); diff --git a/typo3/sysext/core/Classes/Resource/Index/FileIndexRepository.php b/typo3/sysext/core/Classes/Resource/Index/FileIndexRepository.php index 379dc4549b319a5608c715e8dff265a49b07efa2..d9cdac8c64e9dbb4ce467e74a1cff3b8d046575b 100644 --- a/typo3/sysext/core/Classes/Resource/Index/FileIndexRepository.php +++ b/typo3/sysext/core/Classes/Resource/Index/FileIndexRepository.php @@ -333,7 +333,7 @@ class FileIndexRepository implements SingletonInterface $this->table, $data ); - $data['uid'] = $connection->lastInsertId($this->table); + $data['uid'] = (int)$connection->lastInsertId($this->table); $this->updateRefIndex($data['uid']); $this->eventDispatcher->dispatch(new AfterFileAddedToIndexEvent($data['uid'], $data)); return $data['uid']; diff --git a/typo3/sysext/extensionmanager/Classes/Utility/Parser/AbstractExtensionXmlParser.php b/typo3/sysext/extensionmanager/Classes/Utility/Parser/AbstractExtensionXmlParser.php index 4ab8bb3038dd138a535e8b568b620c9ae9f76638..3ae4aa46321a73ede00fe810cbe1bb1a25bc16ca 100644 --- a/typo3/sysext/extensionmanager/Classes/Utility/Parser/AbstractExtensionXmlParser.php +++ b/typo3/sysext/extensionmanager/Classes/Utility/Parser/AbstractExtensionXmlParser.php @@ -21,13 +21,6 @@ namespace TYPO3\CMS\Extensionmanager\Utility\Parser; */ abstract class AbstractExtensionXmlParser implements \SplSubject { - /** - * Keeps XML parser instance. - * - * @var mixed - */ - protected $objXml; - /** * Keeps name of required PHP extension * for this class to work properly. diff --git a/typo3/sysext/extensionmanager/Classes/Utility/Parser/ExtensionXmlPullParser.php b/typo3/sysext/extensionmanager/Classes/Utility/Parser/ExtensionXmlPullParser.php index 395aaf019858a2646ef97d7796ede0704da9e4d1..5776e7a90ccdf71286c75367b47fadd028dced4b 100644 --- a/typo3/sysext/extensionmanager/Classes/Utility/Parser/ExtensionXmlPullParser.php +++ b/typo3/sysext/extensionmanager/Classes/Utility/Parser/ExtensionXmlPullParser.php @@ -26,12 +26,15 @@ use TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException; */ class ExtensionXmlPullParser extends AbstractExtensionXmlParser { + protected \XMLReader $xmlReader; + /** * Class constructor. */ public function __construct() { $this->requiredPhpExtensions = 'xmlreader'; + $this->createParser(); } /** @@ -39,7 +42,7 @@ class ExtensionXmlPullParser extends AbstractExtensionXmlParser */ protected function createParser() { - $this->objXml = new \XMLReader(); + $this->xmlReader = new \XMLReader(); } /** @@ -51,27 +54,24 @@ class ExtensionXmlPullParser extends AbstractExtensionXmlParser public function parseXml($file) { $this->createParser(); - if (!(is_object($this->objXml) && get_class($this->objXml) === \XMLReader::class)) { - throw new ExtensionManagerException('Unable to create XML parser.', 1342640540); - } - if ($this->objXml->open($file, 'utf-8') === false) { + if ($this->xmlReader->open($file, 'utf-8') === false) { throw new ExtensionManagerException( sprintf('Unable to open file resource %s.', $file), 1476108651 ); } - while ($this->objXml->read()) { - if ($this->objXml->nodeType == \XMLReader::ELEMENT) { - $this->startElement($this->objXml->name); + while ($this->xmlReader->read()) { + if ($this->xmlReader->nodeType == \XMLReader::ELEMENT) { + $this->startElement($this->xmlReader->name); } else { - if ($this->objXml->nodeType == \XMLReader::END_ELEMENT) { - $this->endElement($this->objXml->name); + if ($this->xmlReader->nodeType == \XMLReader::END_ELEMENT) { + $this->endElement($this->xmlReader->name); } else { continue; } } } - $this->objXml->close(); + $this->xmlReader->close(); } /** @@ -83,10 +83,10 @@ class ExtensionXmlPullParser extends AbstractExtensionXmlParser { switch ($elementName) { case 'extension': - $this->extensionKey = $this->objXml->getAttribute('extensionkey'); + $this->extensionKey = $this->xmlReader->getAttribute('extensionkey'); break; case 'version': - $this->version = $this->objXml->getAttribute('version'); + $this->version = $this->xmlReader->getAttribute('version'); break; case 'downloadcounter': // downloadcounter could be a child node of @@ -173,13 +173,13 @@ class ExtensionXmlPullParser extends AbstractExtensionXmlParser protected function getElementValue(&$elementName) { $value = null; - if (!$this->objXml->isEmptyElement) { + if (!$this->xmlReader->isEmptyElement) { $value = ''; - while ($this->objXml->read()) { - if ($this->objXml->nodeType == \XMLReader::TEXT || $this->objXml->nodeType == \XMLReader::CDATA || $this->objXml->nodeType == \XMLReader::WHITESPACE || $this->objXml->nodeType == \XMLReader::SIGNIFICANT_WHITESPACE) { - $value .= $this->objXml->value; + while ($this->xmlReader->read()) { + if ($this->xmlReader->nodeType == \XMLReader::TEXT || $this->xmlReader->nodeType == \XMLReader::CDATA || $this->xmlReader->nodeType == \XMLReader::WHITESPACE || $this->xmlReader->nodeType == \XMLReader::SIGNIFICANT_WHITESPACE) { + $value .= $this->xmlReader->value; } else { - if ($this->objXml->nodeType == \XMLReader::END_ELEMENT && $this->objXml->name === $elementName) { + if ($this->xmlReader->nodeType == \XMLReader::END_ELEMENT && $this->xmlReader->name === $elementName) { break; } } diff --git a/typo3/sysext/extensionmanager/Classes/Utility/Parser/ExtensionXmlPushParser.php b/typo3/sysext/extensionmanager/Classes/Utility/Parser/ExtensionXmlPushParser.php index fe0411adbb3ff04641f4e603fb8b845346309c70..60640578991b1b17e15e99e4b230caf4ec603771 100644 --- a/typo3/sysext/extensionmanager/Classes/Utility/Parser/ExtensionXmlPushParser.php +++ b/typo3/sysext/extensionmanager/Classes/Utility/Parser/ExtensionXmlPushParser.php @@ -30,6 +30,19 @@ use TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException; */ class ExtensionXmlPushParser extends AbstractExtensionXmlParser { + /** + * Property to store the xml parser resource in when run with PHP <= 7.4 + * + * @var resource|null + * @deprecated will be removed as soon as the minimum version of TYPO3 is 8.0 + */ + protected $legacyXmlParserResource; + + /** + * Property to store the xml parser resource in when run with PHP >= 8.0 + */ + protected ?\XMLParser $xmlParser = null; + /** * Keeps current data of element to process. * @@ -43,6 +56,7 @@ class ExtensionXmlPushParser extends AbstractExtensionXmlParser public function __construct() { $this->requiredPhpExtensions = 'xml'; + $this->createParser(); } /** @@ -50,8 +64,13 @@ class ExtensionXmlPushParser extends AbstractExtensionXmlParser */ protected function createParser() { - $this->objXml = xml_parser_create(); - xml_set_object($this->objXml, $this); + if (PHP_MAJOR_VERSION >= 8) { + $this->xmlParser = xml_parser_create(); + xml_set_object($this->xmlParser, $this); + } else { + $this->legacyXmlParserResource = xml_parser_create(); + xml_set_object($this->legacyXmlParserResource, $this); + } } /** @@ -63,32 +82,92 @@ class ExtensionXmlPushParser extends AbstractExtensionXmlParser public function parseXml($file) { $this->createParser(); - if (!is_resource($this->objXml) && !$this->objXml instanceof \XmlParser) { - throw new ExtensionManagerException('Unable to create XML parser.', 1342640663); - } - // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept - $previousValueOfEntityLoader = null; if (PHP_MAJOR_VERSION < 8) { - $previousValueOfEntityLoader = libxml_disable_entity_loader(true); + $this->parseWithLegacyResource($file); + return; } + + if ($this->xmlParser === null) { + throw $this->createUnableToCreateXmlParseException(); + } + + /** @var \XMLParser $parser */ + $parser = $this->xmlParser; + // keep original character case of XML document - xml_parser_set_option($this->objXml, XML_OPTION_CASE_FOLDING, 0); - xml_parser_set_option($this->objXml, XML_OPTION_SKIP_WHITE, 0); - xml_parser_set_option($this->objXml, XML_OPTION_TARGET_ENCODING, 'utf-8'); - xml_set_element_handler($this->objXml, [$this, 'startElement'], [$this, 'endElement']); - xml_set_character_data_handler($this->objXml, [$this, 'characterData']); + xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); + xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0); + xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, 'utf-8'); + xml_set_element_handler($parser, [$this, 'startElement'], [$this, 'endElement']); + xml_set_character_data_handler($parser, [$this, 'characterData']); if (!($fp = fopen($file, 'r'))) { - throw new ExtensionManagerException(sprintf('Unable to open file resource %s.', $file), 1342640689); + throw $this->createUnableToOpenFileResourceException($file); } while ($data = fread($fp, 4096)) { - if (!xml_parse($this->objXml, $data, feof($fp))) { - throw new ExtensionManagerException(sprintf('XML error %s in line %u of file resource %s.', xml_error_string(xml_get_error_code($this->objXml)), xml_get_current_line_number($this->objXml), $file), 1342640703); + if (!xml_parse($parser, $data, feof($fp))) { + throw $this->createXmlErrorException($parser, $file); } } - if (PHP_MAJOR_VERSION < 8) { - libxml_disable_entity_loader($previousValueOfEntityLoader); + xml_parser_free($parser); + } + + /** + * @throws ExtensionManagerException + * @internal + */ + private function parseWithLegacyResource(string $file) + { + if ($this->legacyXmlParserResource === null) { + throw $this->createUnableToCreateXmlParseException(); } - xml_parser_free($this->objXml); + + /** @var resource $parser */ + $parser = $this->legacyXmlParserResource; + + // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept + $previousValueOfEntityLoader = libxml_disable_entity_loader(true); + + // keep original character case of XML document + xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); + xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0); + xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, 'utf-8'); + xml_set_element_handler($parser, [$this, 'startElement'], [$this, 'endElement']); + xml_set_character_data_handler($parser, [$this, 'characterData']); + if (!($fp = fopen($file, 'r'))) { + throw $this->createUnableToOpenFileResourceException($file); + } + while ($data = fread($fp, 4096)) { + if (!xml_parse($parser, $data, feof($fp))) { + throw $this->createXmlErrorException($parser, $file); + } + } + + libxml_disable_entity_loader($previousValueOfEntityLoader); + + xml_parser_free($parser); + } + + private function createUnableToCreateXmlParseException(): ExtensionManagerException + { + return new ExtensionManagerException('Unable to create XML parser.', 1342640663); + } + + private function createUnableToOpenFileResourceException(string $file): ExtensionManagerException + { + return new ExtensionManagerException(sprintf('Unable to open file resource %s.', $file), 1342640689); + } + + private function createXmlErrorException($parser, string $file): ExtensionManagerException + { + return new ExtensionManagerException( + sprintf( + 'XML error %s in line %u of file resource %s.', + xml_error_string(xml_get_error_code($parser)), + xml_get_current_line_number($parser), + $file + ), + 1342640703 + ); } /** diff --git a/typo3/sysext/form/Classes/ViewHelpers/RenderFormValueViewHelper.php b/typo3/sysext/form/Classes/ViewHelpers/RenderFormValueViewHelper.php index 84527e294871cee2e9c65178a734324d3bfe2aa5..bf4f1a465f46f9712250191489aeb13f64a8d5bf 100644 --- a/typo3/sysext/form/Classes/ViewHelpers/RenderFormValueViewHelper.php +++ b/typo3/sysext/form/Classes/ViewHelpers/RenderFormValueViewHelper.php @@ -118,16 +118,17 @@ class RenderFormValueViewHelper extends AbstractViewHelper RenderingContextInterface $renderingContext ) { $properties = $element->getProperties(); - if (isset($properties['options']) && is_array($properties['options'])) { + $options = $properties['options'] ?? null; + if ($options !== null && is_array($options)) { $properties['options'] = TranslateElementPropertyViewHelper::renderStatic( ['element' => $element, 'property' => 'options'], $renderChildrenClosure, $renderingContext ); if (is_array($value)) { - return self::mapValuesToOptions($value, $properties['options']); + return self::mapValuesToOptions($value, $options); } - return self::mapValueToOption($value, $properties['options']); + return self::mapValueToOption($value, $options); } if (is_object($value)) { return self::processObject($element, $value); diff --git a/typo3/sysext/frontend/Classes/ContentObject/Menu/AbstractMenuContentObject.php b/typo3/sysext/frontend/Classes/ContentObject/Menu/AbstractMenuContentObject.php index 15c45b4ba0fd8a00dfd6c26fd608e33aea95f9ba..801fb7db77f37dcf53b228a2fd12233da714fa45 100644 --- a/typo3/sysext/frontend/Classes/ContentObject/Menu/AbstractMenuContentObject.php +++ b/typo3/sysext/frontend/Classes/ContentObject/Menu/AbstractMenuContentObject.php @@ -236,7 +236,7 @@ abstract class AbstractMenuContentObject $this->tmpl = $tmpl; $this->sys_page = $sys_page; // alwaysActivePIDlist initialized: - $this->conf['alwaysActivePIDlist'] = $this->parent_cObj->stdWrapValue('alwaysActivePIDlist', $this->conf ?? []); + $this->conf['alwaysActivePIDlist'] = (string)$this->parent_cObj->stdWrapValue('alwaysActivePIDlist', $this->conf ?? []); if (trim($this->conf['alwaysActivePIDlist'])) { $this->alwaysActivePIDlist = GeneralUtility::intExplode(',', $this->conf['alwaysActivePIDlist']); } diff --git a/typo3/sysext/frontend/Classes/Imaging/GifBuilder.php b/typo3/sysext/frontend/Classes/Imaging/GifBuilder.php index 4bacc9ccbe2f9a27fc7bf8ac48828de095d89917..e7534b8fc1fd54169389c1378ec37e97b3e0d2f5 100644 --- a/typo3/sysext/frontend/Classes/Imaging/GifBuilder.php +++ b/typo3/sysext/frontend/Classes/Imaging/GifBuilder.php @@ -244,9 +244,9 @@ class GifBuilder extends GraphicalFunctions } // Calculate offsets on elements $this->setup['XY'] = $this->calcOffset($this->setup['XY']); - $this->setup['offset'] = $this->cObj->stdWrapValue('offset', $this->setup ?? []); + $this->setup['offset'] = (string)$this->cObj->stdWrapValue('offset', $this->setup ?? []); $this->setup['offset'] = $this->calcOffset($this->setup['offset']); - $this->setup['workArea'] = $this->cObj->stdWrapValue('workArea', $this->setup ?? []); + $this->setup['workArea'] = (string)$this->cObj->stdWrapValue('workArea', $this->setup ?? []); $this->setup['workArea'] = $this->calcOffset($this->setup['workArea']); foreach ($sKeyArray as $theKey) { $theValue = $this->setup[$theKey]; diff --git a/typo3/sysext/indexed_search/Classes/Indexer.php b/typo3/sysext/indexed_search/Classes/Indexer.php index 7cda13d8a2cb6d669086cc4241dbbfd5121fa876..b283140f782710a67925dd29aeac55d16a7714c8 100644 --- a/typo3/sysext/indexed_search/Classes/Indexer.php +++ b/typo3/sysext/indexed_search/Classes/Indexer.php @@ -383,7 +383,7 @@ class Indexer { // divide head from body ( u-ouh :) ) $contentArr = $this->defaultContentArray; - $contentArr['body'] = stristr($content, '<body'); + $contentArr['body'] = stristr($content, '<body') ?: ''; $headPart = substr($content, 0, -strlen($contentArr['body'])); // get title $this->embracingTags($headPart, 'TITLE', $contentArr['title'], $dummy2, $dummy); diff --git a/typo3/sysext/reports/Classes/Report/Status/ConfigurationStatus.php b/typo3/sysext/reports/Classes/Report/Status/ConfigurationStatus.php index 822568eb6f79b66e03099861f05dd1c9cc3cd25e..5ee5ec92db1041e43d46546b85efb61a7087ce8e 100644 --- a/typo3/sysext/reports/Classes/Report/Status/ConfigurationStatus.php +++ b/typo3/sysext/reports/Classes/Report/Status/ConfigurationStatus.php @@ -24,6 +24,7 @@ use TYPO3\CMS\Core\Database\Query\QueryBuilder; use TYPO3\CMS\Core\Localization\LanguageService; use TYPO3\CMS\Core\Registry; use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Core\Utility\MathUtility; use TYPO3\CMS\Reports\Status as ReportStatus; use TYPO3\CMS\Reports\StatusProviderInterface; @@ -135,6 +136,7 @@ class ConfigurationStatus implements StatusProviderInterface $severity = ReportStatus::OK; $failedConnections = []; $defaultMemcachedPort = ini_get('memcache.default_port'); + $defaultMemcachedPort = MathUtility::canBeInterpretedAsInteger($defaultMemcachedPort) ? (int)$defaultMemcachedPort : 11211; $memcachedServers = $this->getConfiguredMemcachedServers(); if (function_exists('memcache_connect') && is_array($memcachedServers)) { foreach ($memcachedServers as $testServer) { @@ -148,6 +150,7 @@ class ConfigurationStatus implements StatusProviderInterface } if (strpos($testServer, ':') !== false) { [$host, $port] = explode(':', $testServer, 2); + $port = (int)$port; } else { $host = $testServer; $port = $defaultMemcachedPort;