Skip to content

Commit 33c1185

Browse files
committed
[TASK] Mitigate PHP 8.4.0-RC1 breaking changes
Note that this change addresses three different issues, which need to be done in one step, otherwise none of isolated patches would get a +1 CI verification: * Alignment for changed `$escape` parameter handling of CSV related methods, which must be avoided with PHP versions below 8.4.0-beta5, but is required as of PHP 8.4.0-RC1. * This `$escape` issue needs to be addressed directly in the `typo3/testing-framework` and thus needs a raised dependency directly. * PHP 8.4.0.0-RC1 also deprecated the `E_STRICT` constant, which needs to be addressed directly. With [1] the `$escape` parameter for the following method calls * `str_getcsv()` * `fputcsv()` * `fgetcsv()` must be provided as a 1 character long value. Omitting and using the default value will emit a PHP deprecation [2] warning as of PHP 8.4.0-RC1, for example: str_getcsv(): the $escape parameter must be provided as its default value will change To mitigate this, PHP recommends following: It must be passed explicitly either positionally or via named arguments. This change adjusts all occurences (function calls) and ensures that the `$escape` parameter is explicitly provided via specifying all parameters up to that position and not using a `named arguments` approach for easier backporting. The TYPO3 testing framework also needs to be aligned to mitigate `fgetcsv()` issues, and is raised in the same step - otherwise none of these changes would get a green CI pipeline run. The following testing-framework updates are adjusted: * main: simple update `main` pointer * 12.4: Raise to tag `8.2.2` * 11.5: Raise to tag `6.16.10` Used command(s): > composer require --dev "typo3/testing-framework":"^8.2.2" Additionally, PHP 8.4.0-RC1 deprecated the `E_STRICT` constant, which now emits a E_DEPRECATED which leads to failed CI tests. This change introduces a core internal constant with the same integer value, and replaces usages with this constant to mitigate the E_DEPRECATION. This constant can then be dropped with TYPO3 v14, preventing a breaking change at this time. [3][4] [1] php/php-src#15569 [2] https://github.com/php/php-src/blob/ebee8df27ed/UPGRADING#L617-L622 [3] https://github.com/php/php-src/blob/ebee8df27edf7/UPGRADING#L47-L49 [4] php/php-src#13053 Resolves: #105155 Releases: main, 12.4, 11.5 Change-Id: Ie8b7d46eeb75ba6e32c0e8f6e7e947775083cc15 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/86376 Tested-by: core-ci <typo3@b13.com> Tested-by: Stefan Bürk <stefan@buerk.tech> Reviewed-by: Garvin Hicking <gh@faktor-e.de> Reviewed-by: Stefan Bürk <stefan@buerk.tech> Tested-by: Garvin Hicking <gh@faktor-e.de>
1 parent d9ded8a commit 33c1185

File tree

11 files changed

+50
-16
lines changed

11 files changed

+50
-16
lines changed

Classes/Error/ErrorHandler.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,11 @@ class ErrorHandler implements ErrorHandlerInterface, LoggerAwareInterface
6262
E_USER_ERROR => 'PHP User Error',
6363
E_USER_WARNING => 'PHP User Warning',
6464
E_USER_NOTICE => 'PHP User Notice',
65-
E_STRICT => 'PHP Runtime Notice',
6665
E_RECOVERABLE_ERROR => 'PHP Catchable Fatal Error',
6766
E_USER_DEPRECATED => 'TYPO3 Deprecation Notice',
6867
E_DEPRECATED => 'PHP Runtime Deprecation Notice',
68+
// @todo Remove intermediate constant E_STRICT_DEPRECATED with TYPO3 v14. E_STRICT (2048) constant deprecated since PHP 8.4.0 RC1.
69+
E_STRICT_DEPRECATED => 'PHP Runtime Notice',
6970
];
7071

7172
/**

Classes/LinkHandling/TypoLinkCodecService.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public function decode($typoLink)
8080
{
8181
$typoLink = trim((string)$typoLink);
8282
if ($typoLink !== '') {
83-
$parts = str_replace(['\\\\', '\\"'], ['\\', '"'], str_getcsv($typoLink, static::$partDelimiter));
83+
$parts = str_replace(['\\\\', '\\"'], ['\\', '"'], str_getcsv($typoLink, static::$partDelimiter, '"', '\\'));
8484
} else {
8585
$parts = [];
8686
}

Classes/Resource/Index/FileIndexRepository.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ public function findByFolders(array $folders, $includeMissing = true, $fileName
242242
);
243243

244244
if (isset($fileName)) {
245-
$nameParts = str_getcsv($fileName, ' ');
245+
$nameParts = str_getcsv($fileName, ' ', '"', '\\');
246246
foreach ($nameParts as $part) {
247247
$part = trim($part);
248248
if ($part !== '') {

Classes/Resource/Search/QueryRestrictions/SearchTermRestriction.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ private function makeQuerySearchByTable(string $tableName, string $tableAlias):
6969
$searchTerm = (string)$this->searchDemand->getSearchTerm();
7070
$constraints = [];
7171

72-
$searchTermParts = str_getcsv($searchTerm, ' ');
72+
$searchTermParts = str_getcsv($searchTerm, ' ', '"', '\\');
7373
foreach ($searchTermParts as $searchTermPart) {
7474
$searchTermPart = trim($searchTermPart);
7575
if ($searchTermPart === '') {

Classes/Utility/ArrayUtility.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ public static function getValueByPath(array $array, array|string $path, string $
181181
// Programming error has to be sanitized before calling the method -> global exception
182182
throw new \RuntimeException('Path must not be empty', 1341397767);
183183
}
184-
$path = str_getcsv($path, $delimiter);
184+
$path = str_getcsv($path, $delimiter, '"', '\\');
185185
}
186186
// Loop through each part and extract its value
187187
$value = $array;
@@ -265,7 +265,7 @@ public static function setValueByPath(array $array, string|array|\ArrayAccess $p
265265
throw new \RuntimeException('Path must not be empty', 1341406194);
266266
}
267267
// Extract parts of the path
268-
$path = str_getcsv($path, $delimiter);
268+
$path = str_getcsv($path, $delimiter, '"', '\\');
269269
}
270270
// Point to the root of the array
271271
$pointer = &$array;
@@ -306,7 +306,7 @@ public static function removeByPath(array $array, string $path, string $delimite
306306
throw new \RuntimeException('Path must not be empty', 1371757718);
307307
}
308308
// Extract parts of the path
309-
$pathSegments = str_getcsv($path, $delimiter);
309+
$pathSegments = str_getcsv($path, $delimiter, '"', '\\');
310310
$pathDepth = count($pathSegments);
311311
$currentDepth = 0;
312312
$pointer = &$array;

Classes/Utility/CsvUtility.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public static function csvToArray(string $input, string $fieldDelimiter = ',', s
5858
if (($handle = fopen('php://memory', 'r+')) !== false) {
5959
fwrite($handle, $input);
6060
rewind($handle);
61-
while (($cells = fgetcsv($handle, 0, $fieldDelimiter, $fieldEnclosure)) !== false) {
61+
while (($cells = fgetcsv($handle, 0, $fieldDelimiter, $fieldEnclosure, '\\')) !== false) {
6262
$maximumCellCount = max(count($cells), $maximumCellCount);
6363
$multiArray[] = preg_replace('|<br */?>|i', LF, $cells);
6464
}
@@ -110,7 +110,7 @@ public static function csvValues(array $row, string $delim = ',', string $quote
110110
} elseif ($type === self::TYPE_PREFIX_CONTROLS) {
111111
$row = array_map(self::prefixControlLiterals(...), $row);
112112
}
113-
fputcsv($resource, $modifier($row), $delim, $quote);
113+
fputcsv($resource, $modifier($row), $delim, $quote, '\\');
114114
fseek($resource, 0);
115115
return stream_get_contents($resource);
116116
}

Configuration/DefaultConfiguration.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,9 +258,13 @@
258258
'productionExceptionHandler' => \TYPO3\CMS\Core\Error\ProductionExceptionHandler::class,
259259
'debugExceptionHandler' => \TYPO3\CMS\Core\Error\DebugExceptionHandler::class,
260260
'errorHandler' => \TYPO3\CMS\Core\Error\ErrorHandler::class,
261-
'errorHandlerErrors' => E_ALL & ~(E_STRICT | E_NOTICE | E_COMPILE_WARNING | E_COMPILE_ERROR | E_CORE_WARNING | E_CORE_ERROR | E_PARSE | E_ERROR),
262-
'exceptionalErrors' => E_ALL & ~(E_STRICT | E_NOTICE | E_COMPILE_WARNING | E_COMPILE_ERROR | E_CORE_WARNING | E_CORE_ERROR | E_PARSE | E_ERROR | E_DEPRECATED | E_USER_DEPRECATED | E_WARNING | E_USER_ERROR | E_USER_NOTICE | E_USER_WARNING),
263-
'belogErrorReporting' => E_ALL & ~(E_STRICT | E_NOTICE),
261+
// @todo Remove intermediate constant E_STRICT_DEPRECATED with TYPO3 v14. E_STRICT (2048) constant deprecated since PHP 8.4.0 RC1.
262+
'errorHandlerErrors' => E_ALL & ~(E_STRICT_DEPRECATED | E_NOTICE | E_COMPILE_WARNING | E_COMPILE_ERROR | E_CORE_WARNING | E_CORE_ERROR | E_PARSE | E_ERROR),
263+
// @todo Remove intermediate constant E_STRICT_DEPRECATED with TYPO3 v14. E_STRICT (2048) constant deprecated since PHP 8.4.0 RC1.
264+
'exceptionalErrors' => E_ALL & ~(E_STRICT_DEPRECATED | E_NOTICE | E_COMPILE_WARNING | E_COMPILE_ERROR | E_CORE_WARNING | E_CORE_ERROR | E_PARSE | E_ERROR | E_DEPRECATED | E_USER_DEPRECATED | E_WARNING | E_USER_ERROR | E_USER_NOTICE | E_USER_WARNING),
265+
// @todo Remove intermediate constant E_STRICT_DEPRECATED with TYPO3 v14. E_STRICT (2048) constant deprecated since PHP 8.4.0 RC1.
266+
'belogErrorReporting' => E_ALL & ~(E_STRICT_DEPRECATED | E_NOTICE),
267+
'allowedPhpDisableFunctions' => [],
264268
'locallangXMLOverride' => [], // For extension/overriding of the arrays in 'locallang' files in frontend and backend.
265269
'generateApacheHtaccess' => 1,
266270
'ipAnonymization' => 1,

Resources/PHP/DeprecatedConstants.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the TYPO3 CMS project.
5+
*
6+
* It is free software; you can redistribute it and/or modify it under
7+
* the terms of the GNU General Public License, either version 2
8+
* of the License, or any later version.
9+
*
10+
* For the full copyright and license information, please read the
11+
* LICENSE.txt file that was distributed with this source code.
12+
*
13+
* The TYPO3 project - inspiring people to share!
14+
*/
15+
16+
/**
17+
* @internal only for TYPO3 internal work and not part of public API. Remove usage in custom extension code to mitigate
18+
* PHP deprecated constant E_STRICT.
19+
* @deprecated since v13, will be removed in v14. This constant is only for TYPO3 internal usage to replace the
20+
* deprecated `E_STRICT` constant of PHP since PHP 8.4.0 RC1 to avoid E_DEPRECATED messages within
21+
* automatic testing.
22+
*/
23+
define('E_STRICT_DEPRECATED', 2048);

Tests/Functional/Error/ErrorHandlerTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ public function handleErrorOnlyHandlesRegisteredErrorLevels(): void
8888
$logger->expects(self::never())->method('log');
8989

9090
$coreErrorHandler = new ErrorHandler(
91-
E_ALL & ~(E_STRICT | E_NOTICE | E_COMPILE_WARNING | E_COMPILE_ERROR | E_CORE_WARNING | E_CORE_ERROR | E_PARSE | E_ERROR)
91+
// @todo Remove intermediate constant E_STRICT_DEPRECATED with TYPO3 v14. E_STRICT (2048) constant deprecated since PHP 8.4.0 RC1.
92+
E_ALL & ~(E_STRICT_DEPRECATED | E_NOTICE | E_COMPILE_WARNING | E_COMPILE_ERROR | E_CORE_WARNING | E_CORE_ERROR | E_PARSE | E_ERROR)
9293
);
9394
$coreErrorHandler->setLogger($logger);
9495

Tests/Unit/Error/ErrorHandlerTest.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,10 @@ final class ErrorHandlerTest extends UnitTestCase
4141
protected LoggerInterface $trackingLogger;
4242

4343
// These are borrowed from DefaultConfiguration.php.
44-
protected const DEFAULT_ERROR_HANDLER_LEVELS = E_ALL & ~(E_STRICT | E_NOTICE | E_COMPILE_WARNING | E_COMPILE_ERROR | E_CORE_WARNING | E_CORE_ERROR | E_PARSE | E_ERROR);
45-
protected const DEFAULT_EXCEPTIONAL_ERROR_LEVELS = E_ALL & ~(E_STRICT | E_NOTICE | E_COMPILE_WARNING | E_COMPILE_ERROR | E_CORE_WARNING | E_CORE_ERROR | E_PARSE | E_ERROR | E_DEPRECATED | E_USER_DEPRECATED | E_WARNING | E_USER_ERROR | E_USER_NOTICE | E_USER_WARNING);
44+
// @todo Remove intermediate constant E_STRICT_DEPRECATED with TYPO3 v14. E_STRICT (2048) constant deprecated since PHP 8.4.0 RC1.
45+
protected const DEFAULT_ERROR_HANDLER_LEVELS = E_ALL & ~(E_STRICT_DEPRECATED | E_NOTICE | E_COMPILE_WARNING | E_COMPILE_ERROR | E_CORE_WARNING | E_CORE_ERROR | E_PARSE | E_ERROR);
46+
// @todo Remove intermediate constant E_STRICT_DEPRECATED with TYPO3 v14. E_STRICT (2048) constant deprecated since PHP 8.4.0 RC1.
47+
protected const DEFAULT_EXCEPTIONAL_ERROR_LEVELS = E_ALL & ~(E_STRICT_DEPRECATED | E_NOTICE | E_COMPILE_WARNING | E_COMPILE_ERROR | E_CORE_WARNING | E_CORE_ERROR | E_PARSE | E_ERROR | E_DEPRECATED | E_USER_DEPRECATED | E_WARNING | E_USER_ERROR | E_USER_NOTICE | E_USER_WARNING);
4648

4749
protected bool $resetSingletonInstances = true;
4850

composer.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@
116116
"TYPO3\\CMS\\Core\\": "Classes/"
117117
},
118118
"classmap": ["Resources/PHP/"],
119-
"files": ["Resources/PHP/GlobalDebugFunctions.php"]
119+
"files": [
120+
"Resources/PHP/DeprecatedConstants.php",
121+
"Resources/PHP/GlobalDebugFunctions.php"
122+
]
120123
}
121124
}

0 commit comments

Comments
 (0)