Skip to content

Commit

Permalink
[TASK] Mitigate PHP 8.4.0-RC1 breaking changes
Browse files Browse the repository at this point in the history
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 update "typo3/testing-framework"

Note that the backport has been squashed with the later partly
revert using integer values instead of adding a own deprecated
constant #105165 for [3][4].

We can not deprecate a constant and use it at the same time.
We basically traded a deprecated constant with a new deprecated
constant. Therefore this intermediate constant (added without being
released yet in #105155) is removed again and replaced by a plain value.

It's too likely that this constant is used by 3rd party code
(or dependencies like typo3/testing-framework), which then makes
it hard to remove this constant again (despite being deprecated).

Also defining an own constant – that looks like an official PHP
constant – into the global space, has caused immediate confusions
which we want to avoid by using a scalar value + comment.

The reason (possible 3rd party extensions that may still trigger
this error) why this is kept (and not just removed) is also added
to all usages now.

[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
Resolves: #105165
Releases: main, 13.3, 12.4, 11.5
Change-Id: Ie8b7d46eeb75ba6e32c0e8f6e7e947775083cc15
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/86456
Tested-by: Christian Kuhn <[email protected]>
Tested-by: Oliver Hader <[email protected]>
Tested-by: core-ci <[email protected]>
Reviewed-by: Oliver Hader <[email protected]>
Reviewed-by: Christian Kuhn <[email protected]>
  • Loading branch information
sbuerk authored and ohader committed Oct 7, 2024
1 parent 6b9220e commit a807b7e
Show file tree
Hide file tree
Showing 13 changed files with 40 additions and 22 deletions.
9 changes: 5 additions & 4 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ protected function buildConstraintBlock(string $searchString)
*/
protected function splitSearchString(string $searchString): array
{
return str_getcsv($searchString, ' ');
return str_getcsv($searchString, ' ', '"', '\\');
}

/**
Expand Down
5 changes: 4 additions & 1 deletion typo3/sysext/core/Classes/Error/ErrorHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,13 @@ class ErrorHandler implements ErrorHandlerInterface, LoggerAwareInterface
E_USER_ERROR => 'PHP User Error',
E_USER_WARNING => 'PHP User Warning',
E_USER_NOTICE => 'PHP User Notice',
E_STRICT => 'PHP Runtime Notice',
E_RECOVERABLE_ERROR => 'PHP Catchable Fatal Error',
E_USER_DEPRECATED => 'TYPO3 Deprecation Notice',
E_DEPRECATED => 'PHP Runtime Deprecation Notice',
// @todo: Remove 2048 (deprecated E_STRICT) in v14, as this value is no longer used by PHP itself
// and only kept here here because possible custom PHP extensions may still use it.
// See https://wiki.php.net/rfc/deprecations_php_8_4#remove_e_strict_error_level_and_deprecate_e_strict_constant
2048 /* deprecated E_STRICT */ => 'PHP Runtime Notice',
];

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public function decode(string $typoLink): array
{
$typoLink = trim($typoLink);
if ($typoLink !== '') {
$parts = str_replace(['\\\\', '\\"'], ['\\', '"'], str_getcsv($typoLink, self::DELIMITER));
$parts = str_replace(['\\\\', '\\"'], ['\\', '"'], str_getcsv($typoLink, self::DELIMITER, '"', '\\'));
} else {
$parts = [];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ public function findByFolders(array $folders, $includeMissing = true, $fileName
);

if (isset($fileName)) {
$nameParts = str_getcsv($fileName, ' ');
$nameParts = str_getcsv($fileName, ' ', '"', '\\');
foreach ($nameParts as $part) {
$part = trim($part);
if ($part !== '') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ private function makeQuerySearchByTable(string $tableName, string $tableAlias):
$searchTerm = (string)$this->searchDemand->getSearchTerm();
$constraints = [];

$searchTermParts = str_getcsv($searchTerm, ' ');
$searchTermParts = str_getcsv($searchTerm, ' ', '"', '\\');
foreach ($searchTermParts as $searchTermPart) {
$searchTermPart = trim($searchTermPart);
if ($searchTermPart === '') {
Expand Down
6 changes: 3 additions & 3 deletions typo3/sysext/core/Classes/Utility/ArrayUtility.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ public static function getValueByPath(array $array, array|string $path, string $
// Programming error has to be sanitized before calling the method -> global exception
throw new \RuntimeException('Path must not be empty', 1341397767);
}
$path = str_getcsv($path, $delimiter);
$path = str_getcsv($path, $delimiter, '"', '\\');
}
// Loop through each part and extract its value
$value = $array;
Expand Down Expand Up @@ -265,7 +265,7 @@ public static function setValueByPath(array $array, string|array|\ArrayAccess $p
throw new \RuntimeException('Path must not be empty', 1341406194);
}
// Extract parts of the path
$path = str_getcsv($path, $delimiter);
$path = str_getcsv($path, $delimiter, '"', '\\');
}
// Point to the root of the array
$pointer = &$array;
Expand Down Expand Up @@ -306,7 +306,7 @@ public static function removeByPath(array $array, string $path, string $delimite
throw new \RuntimeException('Path must not be empty', 1371757718);
}
// Extract parts of the path
$pathSegments = str_getcsv($path, $delimiter);
$pathSegments = str_getcsv($path, $delimiter, '"', '\\');
$pathDepth = count($pathSegments);
$currentDepth = 0;
$pointer = &$array;
Expand Down
4 changes: 2 additions & 2 deletions typo3/sysext/core/Classes/Utility/CsvUtility.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public static function csvToArray(string $input, string $fieldDelimiter = ',', s
if (($handle = fopen('php://memory', 'r+')) !== false) {
fwrite($handle, $input);
rewind($handle);
while (($cells = fgetcsv($handle, 0, $fieldDelimiter, $fieldEnclosure)) !== false) {
while (($cells = fgetcsv($handle, 0, $fieldDelimiter, $fieldEnclosure, '\\')) !== false) {
$maximumCellCount = max(count($cells), $maximumCellCount);
$multiArray[] = preg_replace('|<br */?>|i', LF, $cells);
}
Expand Down Expand Up @@ -110,7 +110,7 @@ public static function csvValues(array $row, string $delim = ',', string $quote
} elseif ($type === self::TYPE_PREFIX_CONTROLS) {
$row = array_map(self::prefixControlLiterals(...), $row);
}
fputcsv($resource, $modifier($row), $delim, $quote);
fputcsv($resource, $modifier($row), $delim, $quote, '\\');
fseek($resource, 0);
return stream_get_contents($resource);
}
Expand Down
9 changes: 6 additions & 3 deletions typo3/sysext/core/Configuration/DefaultConfiguration.php
Original file line number Diff line number Diff line change
Expand Up @@ -260,9 +260,12 @@
'productionExceptionHandler' => \TYPO3\CMS\Core\Error\ProductionExceptionHandler::class,
'debugExceptionHandler' => \TYPO3\CMS\Core\Error\DebugExceptionHandler::class,
'errorHandler' => \TYPO3\CMS\Core\Error\ErrorHandler::class,
'errorHandlerErrors' => E_ALL & ~(E_STRICT | E_NOTICE | E_COMPILE_WARNING | E_COMPILE_ERROR | E_CORE_WARNING | E_CORE_ERROR | E_PARSE | E_ERROR),
'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),
'belogErrorReporting' => E_ALL & ~(E_STRICT | E_NOTICE),
// @todo: Remove 2048 (deprecated E_STRICT) in v14, as this value is no longer used by PHP itself
// and only kept here here because possible custom PHP extensions may still use it.
// See https://wiki.php.net/rfc/deprecations_php_8_4#remove_e_strict_error_level_and_deprecate_e_strict_constant
'errorHandlerErrors' => E_ALL & ~(2048 /* deprecated E_STRICT */ | E_NOTICE | E_COMPILE_WARNING | E_COMPILE_ERROR | E_CORE_WARNING | E_CORE_ERROR | E_PARSE | E_ERROR),
'exceptionalErrors' => E_ALL & ~(2048 /* deprecated 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),
'belogErrorReporting' => E_ALL & ~(2048 /* deprecated E_STRICT */ | E_NOTICE),
'allowedPhpDisableFunctions' => [],
'locallangXMLOverride' => [], // For extension/overriding of the arrays in 'locallang' files in frontend and backend.
'generateApacheHtaccess' => 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,10 @@ public function handleErrorOnlyHandlesRegisteredErrorLevels(): void
$logger->expects(self::never())->method('log');

$coreErrorHandler = new ErrorHandler(
E_ALL & ~(E_STRICT | E_NOTICE | E_COMPILE_WARNING | E_COMPILE_ERROR | E_CORE_WARNING | E_CORE_ERROR | E_PARSE | E_ERROR)
// @todo: Remove 2048 (deprecated E_STRICT) in v14, as this value is no longer used by PHP itself
// and only kept here here because possible custom PHP extensions may still use it.
// See https://wiki.php.net/rfc/deprecations_php_8_4#remove_e_strict_error_level_and_deprecate_e_strict_constant
E_ALL & ~(2048 /* deprecated E_STRICT */ | E_NOTICE | E_COMPILE_WARNING | E_COMPILE_ERROR | E_CORE_WARNING | E_CORE_ERROR | E_PARSE | E_ERROR)
);
$coreErrorHandler->setLogger($logger);

Expand Down
7 changes: 5 additions & 2 deletions typo3/sysext/core/Tests/Unit/Error/ErrorHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,11 @@ final class ErrorHandlerTest extends UnitTestCase
protected LoggerInterface $trackingLogger;

// These are borrowed from DefaultConfiguration.php.
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);
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);
// @todo: Remove 2048 (deprecated E_STRICT) in v14, as this value is no longer used by PHP itself
// and only kept here here because possible custom PHP extensions may still use it.
// See https://wiki.php.net/rfc/deprecations_php_8_4#remove_e_strict_error_level_and_deprecate_e_strict_constant
protected const DEFAULT_ERROR_HANDLER_LEVELS = E_ALL & ~(2048 /* deprecated E_STRICT */ | E_NOTICE | E_COMPILE_WARNING | E_COMPILE_ERROR | E_CORE_WARNING | E_CORE_ERROR | E_PARSE | E_ERROR);
protected const DEFAULT_EXCEPTIONAL_ERROR_LEVELS = E_ALL & ~(2048 /* deprecated 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);

protected bool $resetSingletonInstances = true;

Expand Down
4 changes: 3 additions & 1 deletion typo3/sysext/core/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@
"TYPO3\\CMS\\Core\\": "Classes/"
},
"classmap": ["Resources/PHP/"],
"files": ["Resources/PHP/GlobalDebugFunctions.php"]
"files": [
"Resources/PHP/GlobalDebugFunctions.php"
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,13 @@ final class PhpErrorCodeViewHelper extends AbstractViewHelper
E_USER_ERROR => 'E_USER_ERROR',
E_USER_WARNING => 'E_USER_WARNING',
E_USER_NOTICE => 'E_USER_NOTICE',
E_STRICT => 'E_STRICT',
E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR',
E_DEPRECATED => 'E_DEPRECATED',
E_USER_DEPRECATED => 'E_USER_DEPRECATED',
// @todo: Remove 2048 (deprecated E_STRICT) in v14, as this value is no longer used by PHP itself
// and only kept here here because possible custom PHP extensions may still use it.
// See https://wiki.php.net/rfc/deprecations_php_8_4#remove_e_strict_error_level_and_deprecate_e_strict_constant
2048 /* deprecated E_STRICT */ => 'PHP Runtime Notice',
];

public function initializeArguments(): void
Expand Down

0 comments on commit a807b7e

Please sign in to comment.