Commit cd2c9762 authored by Alexander Schnitzler's avatar Alexander Schnitzler Committed by Daniel Goerz
Browse files

[TASK] Fix phpstan checkFunctionArgumentTypes errors in ext:core Utility

This patch fixes incompatible type usage in function arguments
and is preparatory work for introducing native type hints and
strict mode in all core files.

Releases: master, 10.4
Resolves: #92279
Change-Id: I469892a56334a13ab19df17aeaa39a68226b7510
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/65679


Tested-by: default avatarAlexander Schnitzler <git@alexanderschnitzler.de>
Tested-by: default avatarTYPO3com <noreply@typo3.com>
Tested-by: Daniel Goerz's avatarDaniel Goerz <daniel.goerz@posteo.de>
Reviewed-by: default avatarAlexander Schnitzler <git@alexanderschnitzler.de>
Reviewed-by: Daniel Goerz's avatarDaniel Goerz <daniel.goerz@posteo.de>
parent 50ab10b7
......@@ -679,7 +679,7 @@ class ArrayUtility
*
* @param array $array The initial array to be filtered/reduced
* @param mixed $keepItems The items which are allowed/kept in the array - accepts array or csv string
* @param string $getValueFunc (optional) Callback function used to get the value to keep
* @param callable|null $getValueFunc (optional) Callback function used to get the value to keep
* @return array The filtered/reduced array with the kept items
*/
public static function keepItemsInArray(array $array, $keepItems, $getValueFunc = null)
......@@ -837,7 +837,7 @@ class ArrayUtility
if (is_array($value)) {
$result[$key] = self::stripTagsFromValuesRecursive($value);
} elseif (is_string($value) || (is_object($value) && method_exists($value, '__toString'))) {
$result[$key] = strip_tags($value);
$result[$key] = strip_tags((string)$value);
}
}
return $result;
......
......@@ -453,7 +453,7 @@ class CommandUtility
$isUTF8Filesystem = !empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['UTF8filesystem']);
$currentLocale = false;
if ($isUTF8Filesystem) {
$currentLocale = setlocale(LC_CTYPE, 0);
$currentLocale = setlocale(LC_CTYPE, '0');
setlocale(LC_CTYPE, $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale']);
}
......
......@@ -40,6 +40,7 @@ class CsvUtility
fwrite($handle, $input);
rewind($handle);
while (($cells = fgetcsv($handle, 0, $fieldDelimiter, $fieldEnclosure)) !== false) {
$cells = is_array($cells) ? $cells : [];
$maximumCellCount = max(count($cells), $maximumCellCount);
$multiArray[] = preg_replace('|<br */?>|i', LF, $cells);
}
......
......@@ -1596,7 +1596,7 @@ tt_content.' . $key . $suffix . ' {
$phpCodeToCache[] = ' */';
$phpCodeToCache[] = '';
// Add ext_localconf.php content of extension
$phpCodeToCache[] = trim(file_get_contents($extLocalconfPath));
$phpCodeToCache[] = trim((string)file_get_contents($extLocalconfPath));
$phpCodeToCache[] = '';
$phpCodeToCache[] = '';
}
......@@ -1820,7 +1820,7 @@ tt_content.' . $key . $suffix . ' {
$phpCodeToCache[] = ' */';
$phpCodeToCache[] = '';
// Add ext_tables.php content of extension
$phpCodeToCache[] = trim(file_get_contents($extTablesPath));
$phpCodeToCache[] = trim((string)file_get_contents($extTablesPath));
$phpCodeToCache[] = '';
}
}
......
......@@ -136,11 +136,11 @@ class BasicFileUtility
// Handle UTF-8 characters
if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['UTF8filesystem']) {
// allow ".", "-", 0-9, a-z, A-Z and everything beyond U+C0 (latin capital letter a with grave)
$cleanFileName = preg_replace('/[' . self::UNSAFE_FILENAME_CHARACTER_EXPRESSION . ']/u', '_', trim($fileName));
$cleanFileName = preg_replace('/[' . self::UNSAFE_FILENAME_CHARACTER_EXPRESSION . ']/u', '_', trim($fileName)) ?? '';
} else {
$fileName = GeneralUtility::makeInstance(CharsetConverter::class)->utf8_char_mapping($fileName);
// Replace unwanted characters by underscores
$cleanFileName = preg_replace('/[' . self::UNSAFE_FILENAME_CHARACTER_EXPRESSION . '\\xC0-\\xFF]/', '_', trim($fileName));
$cleanFileName = preg_replace('/[' . self::UNSAFE_FILENAME_CHARACTER_EXPRESSION . '\\xC0-\\xFF]/', '_', trim($fileName)) ?? '';
}
// Strip trailing dots and return
return rtrim($cleanFileName, '.');
......
......@@ -251,9 +251,10 @@ class GeneralUtility
$mask = false;
}
if ((int)$mask) {
$mask = (int)$mask;
// "192.168.3.0/24"
$lnet = ip2long($test);
$lip = ip2long($baseIP);
$lnet = (int)ip2long($test);
$lip = (int)ip2long($baseIP);
$binnet = str_pad(decbin($lnet), 32, '0', STR_PAD_LEFT);
$firstpart = substr($binnet, 0, $mask);
$binip = str_pad(decbin($lip), 32, '0', STR_PAD_LEFT);
......@@ -307,13 +308,15 @@ class GeneralUtility
} elseif ($maskInt == 128) {
$success = $test === $baseIP;
} else {
$testBin = inet_pton($test);
$baseIPBin = inet_pton($baseIP);
$testBin = (string)inet_pton($test);
$baseIPBin = (string)inet_pton($baseIP);
$success = true;
// Modulo is 0 if this is a 8-bit-boundary
$maskIntModulo = $maskInt % 8;
$numFullCharactersUntilBoundary = (int)($maskInt / 8);
if (strpos($testBin, substr($baseIPBin, 0, $numFullCharactersUntilBoundary)) !== 0) {
$substring = (string)substr($baseIPBin, 0, $numFullCharactersUntilBoundary);
if (strpos($testBin, $substring) !== 0) {
$success = false;
} elseif ($maskIntModulo > 0) {
// If not an 8-bit-boundary, check bits of last character
......@@ -450,7 +453,7 @@ class GeneralUtility
// Resolve hostname
// Note: this is reverse-lookup and can be randomly set as soon as somebody is able to set
// the reverse-DNS for his IP (security when for example used with REMOTE_ADDR)
$baseHostName = gethostbyaddr($baseHost);
$baseHostName = (string)gethostbyaddr($baseHost);
if ($baseHostName === $baseHost) {
// Unable to resolve hostname
return false;
......@@ -835,7 +838,7 @@ class GeneralUtility
*/
public static function camelCaseToLowerCaseUnderscored($string)
{
$value = preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $string);
$value = preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $string) ?? '';
return mb_strtolower($value, 'utf-8');
}
......@@ -909,7 +912,7 @@ class GeneralUtility
*/
public static function intExplode($delimiter, $string, $removeEmptyValues = false, $limit = 0)
{
$result = explode($delimiter, $string);
$result = explode($delimiter, $string) ?: [];
foreach ($result as $key => &$value) {
if ($removeEmptyValues && ($value === '' || trim($value) === '')) {
unset($result[$key]);
......@@ -957,7 +960,7 @@ class GeneralUtility
if ($count <= 1) {
return [$string];
}
$explodedValues = explode($delimiter, strrev($string), $count);
$explodedValues = explode($delimiter, strrev($string), $count) ?: [];
$explodedValues = array_map('strrev', $explodedValues);
return array_reverse($explodedValues);
}
......@@ -976,7 +979,7 @@ class GeneralUtility
*/
public static function trimExplode($delim, $string, $removeEmptyValues = false, $limit = 0)
{
$result = explode($delim, $string);
$result = explode($delim, $string) ?: [];
if ($removeEmptyValues) {
$temp = [];
foreach ($result as $value) {
......@@ -1106,7 +1109,7 @@ class GeneralUtility
*
* @param string $tag HTML-tag string (or attributes only)
* @param bool $decodeEntities Whether to decode HTML entities
* @return string[] Array with the attribute values.
* @return array<string, string> Array with the attribute values.
*/
public static function get_tag_attributes($tag, bool $decodeEntities = false)
{
......@@ -1124,7 +1127,7 @@ class GeneralUtility
$name = '';
}
} else {
if ($key = strtolower(preg_replace('/[^[:alnum:]_\\:\\-]/', '', $val))) {
if ($key = strtolower(preg_replace('/[^[:alnum:]_\\:\\-]/', '', $val) ?? '')) {
$attributes[$key] = '';
$name = $key;
}
......@@ -1146,7 +1149,7 @@ class GeneralUtility
*/
public static function split_tag_attributes($tag)
{
$tag_tmp = trim(preg_replace('/^<[^[:space:]]*/', '', trim($tag)));
$tag_tmp = trim(preg_replace('/^<[^[:space:]]*/', '', trim($tag)) ?? '');
// Removes any > in the end of the string
$tag_tmp = trim(rtrim($tag_tmp, '>'));
$value = [];
......@@ -1709,13 +1712,13 @@ class GeneralUtility
}
if (static::isAllowedAbsPath($path)) {
if (@is_file($path)) {
$targetPermissions = $GLOBALS['TYPO3_CONF_VARS']['SYS']['fileCreateMask'] ?? '0644';
$targetPermissions = (string)($GLOBALS['TYPO3_CONF_VARS']['SYS']['fileCreateMask'] ?? '0644');
} elseif (@is_dir($path)) {
$targetPermissions = $GLOBALS['TYPO3_CONF_VARS']['SYS']['folderCreateMask'] ?? '0755';
$targetPermissions = (string)($GLOBALS['TYPO3_CONF_VARS']['SYS']['folderCreateMask'] ?? '0755');
}
if (!empty($targetPermissions)) {
// make sure it's always 4 digits
$targetPermissions = str_pad($targetPermissions, 4, 0, STR_PAD_LEFT);
$targetPermissions = str_pad($targetPermissions, 4, '0', STR_PAD_LEFT);
$targetPermissions = octdec($targetPermissions);
// "@" is there because file is not necessarily OWNED by the user
$result = @chmod($path, $targetPermissions);
......@@ -1891,9 +1894,9 @@ class GeneralUtility
if (!@is_dir($currentPath)) {
do {
$firstCreatedPath = $currentPath;
$separatorPosition = strrpos($currentPath, DIRECTORY_SEPARATOR);
$separatorPosition = (int)strrpos($currentPath, DIRECTORY_SEPARATOR);
$currentPath = substr($currentPath, 0, $separatorPosition);
} while (!is_dir($currentPath) && $separatorPosition !== false);
} while (!is_dir($currentPath) && $separatorPosition > 0);
$result = @mkdir($fullDirectoryPath, $permissionMask, true);
// Check existence of directory again to avoid race condition. Directory could have get created by another process between previous is_dir() and mkdir()
if (!$result && !@is_dir($fullDirectoryPath)) {
......@@ -1914,7 +1917,7 @@ class GeneralUtility
{
$OK = false;
// Remove trailing slash
$path = preg_replace('|/$|', '', $path);
$path = preg_replace('|/$|', '', $path) ?? '';
$isWindows = DIRECTORY_SEPARATOR === '\\';
if (file_exists($path)) {
$OK = true;
......@@ -2068,7 +2071,7 @@ class GeneralUtility
if ($regDirs) {
$fileArr[md5($path)] = $path;
}
$fileArr = array_merge($fileArr, self::getFilesInDir($path, $extList, 1, 1, $excludePattern));
$fileArr = array_merge($fileArr, (array)self::getFilesInDir($path, $extList, true, '', $excludePattern));
$dirs = self::get_dirs($path);
if ($recursivityLevels > 0 && is_array($dirs)) {
foreach ($dirs as $subdirs) {
......@@ -2180,10 +2183,12 @@ class GeneralUtility
*/
public static function getMaxUploadFileSize()
{
$uploadMaxFilesize = (string)ini_get('upload_max_filesize');
$postMaxSize = (string)ini_get('post_max_size');
// Check for PHP restrictions of the maximum size of one of the $_FILES
$phpUploadLimit = self::getBytesFromSizeMeasurement(ini_get('upload_max_filesize'));
$phpUploadLimit = self::getBytesFromSizeMeasurement($uploadMaxFilesize);
// Check for PHP restrictions of the maximum $_POST size
$phpPostLimit = self::getBytesFromSizeMeasurement(ini_get('post_max_size'));
$phpPostLimit = self::getBytesFromSizeMeasurement($postMaxSize);
// If the total amount of post data is smaller (!) than the upload_max_filesize directive,
// then this is the real limit in PHP
$phpUploadLimit = $phpPostLimit > 0 && $phpPostLimit < $phpUploadLimit ? $phpPostLimit : $phpUploadLimit;
......@@ -2206,7 +2211,7 @@ class GeneralUtility
} elseif (stripos($measurement, 'K')) {
$bytes *= 1024;
}
return $bytes;
return (int)$bytes;
}
/**
......@@ -2478,7 +2483,7 @@ class GeneralUtility
$ip = '';
}
}
if (self::validIP($ip)) {
if (self::validIP((string)$ip)) {
$retVal = $ip;
}
}
......@@ -2991,13 +2996,14 @@ class GeneralUtility
self::mkdir_deep($temporaryPath);
}
if ($fileSuffix === '') {
$tempFileName = $temporaryPath . PathUtility::basename(tempnam($temporaryPath, $filePrefix));
$path = (string)tempnam($temporaryPath, $filePrefix);
$tempFileName = $temporaryPath . PathUtility::basename($path);
} else {
do {
$tempFileName = $temporaryPath . $filePrefix . random_int(1, PHP_INT_MAX) . $fileSuffix;
} while (file_exists($tempFileName));
touch($tempFileName);
clearstatcache(null, $tempFileName);
clearstatcache(false, $tempFileName);
}
return $tempFileName;
}
......@@ -3079,16 +3085,18 @@ class GeneralUtility
if (class_exists($parts[0])) {
// Create object
$classObj = self::makeInstance($parts[0]);
if (method_exists($classObj, $parts[1])) {
$methodName = (string)$parts[1];
$callable = [$classObj, $methodName];
if (is_callable($callable)) {
// Call method:
$content = call_user_func_array([&$classObj, $parts[1]], [&$params, &$ref]);
$content = call_user_func_array($callable, [&$params, &$ref]);
} else {
throw new \InvalidArgumentException('No method name \'' . $parts[1] . '\' in class ' . $parts[0], 1294585865);
}
} else {
throw new \InvalidArgumentException('No class named ' . $parts[0], 1294585866);
}
} elseif (function_exists($funcName)) {
} elseif (function_exists($funcName) && is_callable($funcName)) {
// It's a function
$content = call_user_func_array($funcName, [&$params, &$ref]);
} else {
......@@ -3478,8 +3486,13 @@ class GeneralUtility
*/
public static function quoteJSvalue($value)
{
$json = (string)json_encode(
(string)$value,
JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_TAG
);
return strtr(
json_encode((string)$value, JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_TAG),
$json,
[
'"' => '\'',
'\\\\' => '\\u005C',
......@@ -3499,7 +3512,7 @@ class GeneralUtility
*/
public static function jsonEncodeForHtmlAttribute($value, bool $useHtmlEntities = true): string
{
$json = json_encode($value, JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_TAG);
$json = (string)json_encode($value, JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_TAG);
return $useHtmlEntities ? htmlspecialchars($json) : $json;
}
......
......@@ -114,7 +114,7 @@ class PathUtility
if (count($paths) === 1) {
$commonPath = array_shift($paths);
} elseif (count($paths) > 1) {
$parts = explode('/', array_shift($paths));
$parts = explode('/', (string)array_shift($paths));
$comparePath = '';
$break = false;
foreach ($parts as $part) {
......@@ -164,7 +164,7 @@ class PathUtility
*/
public static function basename($path)
{
$currentLocale = setlocale(LC_CTYPE, 0);
$currentLocale = (string)setlocale(LC_CTYPE, '0');
setlocale(LC_CTYPE, $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale']);
$basename = basename($path);
setlocale(LC_CTYPE, $currentLocale);
......@@ -185,7 +185,7 @@ class PathUtility
*/
public static function dirname($path)
{
$currentLocale = setlocale(LC_CTYPE, 0);
$currentLocale = (string)setlocale(LC_CTYPE, '0');
setlocale(LC_CTYPE, $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale']);
$dirname = dirname($path);
setlocale(LC_CTYPE, $currentLocale);
......@@ -203,11 +203,11 @@ class PathUtility
* @param string $path
* @param int $options
*
* @return string|array
* @return string|string[]
*/
public static function pathinfo($path, $options = null)
{
$currentLocale = setlocale(LC_CTYPE, 0);
$currentLocale = (string)setlocale(LC_CTYPE, '0');
setlocale(LC_CTYPE, $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale']);
$pathinfo = $options == null ? pathinfo($path) : pathinfo($path, $options);
setlocale(LC_CTYPE, $currentLocale);
......
......@@ -34,7 +34,7 @@ class VersionNumberUtility
$version = $versionParts[0];
for ($i = 1; $i < 3; $i++) {
if (!empty($versionParts[$i])) {
$version .= str_pad((int)$versionParts[$i], 3, '0', STR_PAD_LEFT);
$version .= str_pad((string)(int)$versionParts[$i], 3, '0', STR_PAD_LEFT);
} else {
$version .= '000';
}
......@@ -86,7 +86,7 @@ class VersionNumberUtility
$cleanedVersion = GeneralUtility::trimExplode('.', $versions[$i]);
$cleanedVersionCount = count($cleanedVersion);
for ($j = 0; $j < $cleanedVersionCount; $j++) {
$cleanedVersion[$j] = MathUtility::forceIntegerInRange($cleanedVersion[$j], 0, 999);
$cleanedVersion[$j] = MathUtility::forceIntegerInRange((int)$cleanedVersion[$j], 0, 999);
}
$cleanedVersionString = implode('.', $cleanedVersion);
if (static::convertVersionNumberToInteger($cleanedVersionString) === 0) {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment