diff --git a/Ai/Ocr/BasicOcr.php b/Ai/Ocr/BasicOcr.php index a94cb0efb..740c42ed4 100644 --- a/Ai/Ocr/BasicOcr.php +++ b/Ai/Ocr/BasicOcr.php @@ -90,41 +90,41 @@ final class BasicOcr throw new PathException($path); // @codeCoverageIgnore } - $read = \fread($fp, 4); - if ($read === false) { - return []; // @codeCoverageIgnore - } - $magicNumber = \unpack('N', $read)[1]; - $read = \fread($fp, 4); - if ($read === false) { + if (($read = \fread($fp, 4)) === false || ($unpack = \unpack('N', $read)) === false) { return []; // @codeCoverageIgnore } - $numberOfImages = \unpack('N', $read)[1]; + $magicNumber = $unpack[1]; + + if (($read = \fread($fp, 4)) === false || ($unpack = \unpack('N', $read)) === false) { + return []; // @codeCoverageIgnore + } + $numberOfImages = $unpack[1]; if ($limit > 0) { $numberOfImages = \min($numberOfImages, $limit); } - $read = \fread($fp, 4); - if ($read === false) { - return []; // @codeCoverageIgnore - } - $numberOfRows = \unpack('N', $read)[1]; - $read = \fread($fp, 4); - if ($read === false) { + if (($read = \fread($fp, 4)) === false || ($unpack = \unpack('N', $read)) === false) { return []; // @codeCoverageIgnore } - $numberOfColumns = \unpack('N', $read)[1]; + $numberOfRows = $unpack[1]; + + if (($read = \fread($fp, 4)) === false || ($unpack = \unpack('N', $read)) === false) { + return []; // @codeCoverageIgnore + } + $numberOfColumns = $unpack[1]; $images = []; for ($i = 0; $i < $numberOfImages; ++$i) { - $read = \fread($fp, $numberOfRows * $numberOfColumns); - if ($read === false) { + + if (($read = \fread($fp, $numberOfRows * $numberOfColumns)) === false + || ($unpack = \unpack('C*', $read)) === false + ) { return []; // @codeCoverageIgnore } - $images[] = \array_values(\unpack('C*', $read)); + $images[] = \array_values($unpack); } \fclose($fp); @@ -153,17 +153,16 @@ final class BasicOcr throw new PathException($path); // @codeCoverageIgnore } - $read = \fread($fp, 4); - if ($read === false) { - return []; // @codeCoverageIgnore - } - $magicNumber = \unpack('N', $read)[1]; - $read = \fread($fp, 4); - if ($read === false) { + if (($read = \fread($fp, 4)) === false || ($unpack = \unpack('N', $read)) === false) { return []; // @codeCoverageIgnore } - $numberOfLabels = \unpack('N', $read)[1]; + $magicNumber = $unpack[1]; + + if (($read = \fread($fp, 4)) === false || ($unpack = \unpack('N', $read)) === false) { + return []; // @codeCoverageIgnore + } + $numberOfLabels = $unpack[1]; if ($limit > 0) { $numberOfLabels = \min($numberOfLabels, $limit); @@ -171,11 +170,11 @@ final class BasicOcr $labels = []; for ($i = 0; $i < $numberOfLabels; ++$i) { - $read = \fread($fp, 1); - if ($read === false) { + + if (($read = \fread($fp, 1)) === false || ($unpack = \unpack('C', $read)) === false) { return []; // @codeCoverageIgnore } - $labels[] = \unpack('C', $read)[1]; + $labels[] = $unpack[1]; } \fclose($fp); diff --git a/DataStorage/Database/DataMapperAbstract.php b/DataStorage/Database/DataMapperAbstract.php index 5c41d256d..2d0c118a3 100644 --- a/DataStorage/Database/DataMapperAbstract.php +++ b/DataStorage/Database/DataMapperAbstract.php @@ -340,7 +340,7 @@ class DataMapperAbstract implements DataMapperInterface * * @since 1.0.0 */ - public static function withConditional(string $id, mixed $value, array $models = [], string $comparison = '=') /** @todo: return : static */ + public static function withConditional(string $id, mixed $value, array $models = [], string $comparison = '=') : static { self::$conditionals[$id] = [ 'value' => $value, @@ -348,6 +348,7 @@ class DataMapperAbstract implements DataMapperInterface 'comparison' => $comparison, ]; + /** @var static */ return static::class; } @@ -594,7 +595,10 @@ class DataMapperAbstract implements DataMapperInterface } try { - self::$db->con->prepare($query->toSql())->execute(); + $sth = self::$db->con->prepare($query->toSql()); + if ($sth !== false) { + $sth->execute(); + } } catch (\Throwable $t) { \var_dump($t->getMessage()); \var_dump($query->toSql()); @@ -655,7 +659,10 @@ class DataMapperAbstract implements DataMapperInterface $query->insert(static::$primaryField)->value(0); } - self::$db->con->prepare($query->toSql())->execute(); + $sth = self::$db->con->prepare($query->toSql()); + if ($sth !== false) { + $sth->execute(); + } return self::$db->con->lastInsertId(); } @@ -1064,7 +1071,10 @@ class DataMapperAbstract implements DataMapperInterface } try { - self::$db->con->prepare($relQuery->toSql())->execute(); + $sth = self::$db->con->prepare($relQuery->toSql()); + if ($sth !== false) { + $sth->execute(); + } } catch (\Throwable $e) { \var_dump($e->getMessage()); \var_dump($relQuery->toSql()); @@ -1322,7 +1332,10 @@ class DataMapperAbstract implements DataMapperInterface ->where(static::$hasMany[$propertyName]['table'] . '.' . static::$hasMany[$propertyName]['external'], '=', $src) ->where(static::$hasMany[$propertyName]['table'] . '.' . static::$hasMany[$propertyName]['self'], '=', $objId, 'and'); - self::$db->con->prepare($relQuery->toSql())->execute(); + $sth = self::$db->con->prepare($relQuery->toSql()); + if ($sth !== false) { + $sth->execute(); + } } } @@ -1494,7 +1507,10 @@ class DataMapperAbstract implements DataMapperInterface } } - self::$db->con->prepare($query->toSql())->execute(); + $sth = self::$db->con->prepare($query->toSql()); + if ($sth !== false) { + $sth->execute(); + } } /** @@ -1558,7 +1574,10 @@ class DataMapperAbstract implements DataMapperInterface } } - self::$db->con->prepare($query->toSql())->execute(); + $sth = self::$db->con->prepare($query->toSql()); + if ($sth !== false) { + $sth->execute(); + } } /** @@ -1834,7 +1853,10 @@ class DataMapperAbstract implements DataMapperInterface } } - self::$db->con->prepare($query->toSql())->execute(); + $sth = self::$db->con->prepare($query->toSql()); + if ($sth !== false) { + $sth->execute(); + } } /** @@ -3045,9 +3067,13 @@ class DataMapperAbstract implements DataMapperInterface } try { + $results = false; + $sth = self::$db->con->prepare($query->toSql()); - $sth->execute(); - $results = $sth->fetchAll(\PDO::FETCH_ASSOC); + if ($sth !== false) { + $sth->execute(); + $results = $sth->fetchAll(\PDO::FETCH_ASSOC); + } } catch (\Throwable $t) { $results = false; \var_dump($query->toSql()); @@ -3074,10 +3100,13 @@ class DataMapperAbstract implements DataMapperInterface ->from(static::$hasMany[$ref]['table']) ->where(static::$hasMany[$ref]['table'] . '.' . static::$hasMany[$ref]['external'], '=', $refKey); - $sth = self::$db->con->prepare($query->toSql()); - $sth->execute(); + $result = false; - $result = $sth->fetchAll(\PDO::FETCH_NUM); + $sth = self::$db->con->prepare($query->toSql()); + if ($sth !== false) { + $sth->execute(); + $result = $sth->fetchAll(\PDO::FETCH_NUM); + } return $result === false ? [] : \array_column($result, 0); } @@ -3128,9 +3157,10 @@ class DataMapperAbstract implements DataMapperInterface } $sth = self::$db->con->prepare($query->toSql()); - $sth->execute(); - - $cachedTables[$value['table']] = $sth->fetchAll(\PDO::FETCH_COLUMN); + if ($sth !== false) { + $sth->execute(); + $cachedTables[$value['table']] = $sth->fetchAll(\PDO::FETCH_COLUMN); + } } $result[$member] = $cachedTables[$value['table']]; diff --git a/Math/Matrix/Matrix.php b/Math/Matrix/Matrix.php index cd9120526..0c774985f 100644 --- a/Math/Matrix/Matrix.php +++ b/Math/Matrix/Matrix.php @@ -686,7 +686,9 @@ class Matrix implements \ArrayAccess, \Iterator */ public function current() : int { - return $this->offsetGet($this->position); + $row = (int) ($this->position / $this->m); + + return $this->matrix[$row][$this->position - $row * $this->n]; } /** diff --git a/Math/Number/Prime.php b/Math/Number/Prime.php index 0f185aab1..887e43ff0 100644 --- a/Math/Number/Prime.php +++ b/Math/Number/Prime.php @@ -101,7 +101,7 @@ final class Prime } for ($j = 1; $j < $s; ++$j) { - if ($x === null) { + if ($x === null || $x === false) { return false; } diff --git a/Math/Parser/Evaluator.php b/Math/Parser/Evaluator.php index bd18c2ccd..622b03635 100644 --- a/Math/Parser/Evaluator.php +++ b/Math/Parser/Evaluator.php @@ -37,7 +37,9 @@ final class Evaluator */ public static function evaluate(string $equation) : ?float { - if (\substr_count($equation, '(') !== \substr_count($equation, ')') || \preg_match('#[^0-9\+\-\*\/\(\)\ \^\.]#', $equation)) { + if (\substr_count($equation, '(') !== \substr_count($equation, ')') + || \preg_match('#[^0-9\+\-\*\/\(\)\ \^\.]#', $equation) + ) { return null; } @@ -48,8 +50,8 @@ final class Evaluator if (\is_numeric($value)) { $stack[] = $value; } else { - $a = self::parseValue(\array_pop($stack)); - $b = self::parseValue(\array_pop($stack)); + $a = self::parseValue(\array_pop($stack) ?? 0); + $b = self::parseValue(\array_pop($stack) ?? 0); if ($value === '+') { $stack[] = $a + $b; diff --git a/Router/SocketRouter.php b/Router/SocketRouter.php index 5619323eb..3d07eec8a 100644 --- a/Router/SocketRouter.php +++ b/Router/SocketRouter.php @@ -127,7 +127,7 @@ final class SocketRouter implements RouterInterface // if permission check is invalid if ((isset($d['permission']) && $account === null) || (isset($d['permission']) - && !$account->hasPermission( + && !$account?->hasPermission( $d['permission']['type'] ?? null, $orgId, $app, $d['permission']['module'] ?? null, $d['permission']['state'] ?? null ) ) diff --git a/Router/WebRouter.php b/Router/WebRouter.php index 990ef1134..bdbdbbc5f 100644 --- a/Router/WebRouter.php +++ b/Router/WebRouter.php @@ -149,7 +149,7 @@ final class WebRouter implements RouterInterface // if permission check is invalid if ((isset($d['permission']) && $account === null) || (isset($d['permission']) - && !$account->hasPermission( + && !$account?->hasPermission( $d['permission']['type'] ?? 0, $d['permission']['unit'] ?? $orgId, $app, $d['permission']['module'] ?? null, $d['permission']['state'] ?? null ) ) diff --git a/Stdlib/Base/Enum.php b/Stdlib/Base/Enum.php index caac22bda..960d4c8a5 100644 --- a/Stdlib/Base/Enum.php +++ b/Stdlib/Base/Enum.php @@ -55,7 +55,7 @@ abstract class Enum { $reflect = new \ReflectionClass(\get_called_class()); - return $reflect->getConstants(); + return $reflect->getConstants() ?? []; } /** diff --git a/Stdlib/Graph/Graph.php b/Stdlib/Graph/Graph.php index 2af08dd11..e4efd26d7 100644 --- a/Stdlib/Graph/Graph.php +++ b/Stdlib/Graph/Graph.php @@ -354,7 +354,12 @@ class Graph $graph->setNode($node2); } - $node1->setNodeRelative($node2)->setWeight($this->getEdge($node1->getId(), $node2->getId())->getWeight()); + $node1->setNodeRelative($node2) + ->setWeight($this->getEdge( + $node1->getId(), + $node2->getId() + )->getWeight() + ); } return $graph; @@ -543,14 +548,14 @@ class Graph /** * Get longest path between two nodes. * - * @param int|string $node1 Graph node - * @param int|string $node2 Graph node + * @param int|string|Node $node1 Graph node + * @param int|string|Node $node2 Graph node * * @return Node[] * * @since 1.0.0 */ - public function longestPathBetweenNodes(int|string $node1, int|string $node2) : array + public function longestPathBetweenNodes(int|string|Node $node1, int|string|Node $node2) : array { if (!($node1 instanceof Node)) { $node1 = $this->getNode($node1); diff --git a/Stdlib/Map/MultiMap.php b/Stdlib/Map/MultiMap.php index cff78c58b..ec5ef5841 100644 --- a/Stdlib/Map/MultiMap.php +++ b/Stdlib/Map/MultiMap.php @@ -184,11 +184,11 @@ final class MultiMap implements \Countable */ public function get(int|string|array $key) : mixed { - if ($this->keyType === KeyType::SINGLE) { - return $this->getSingle($key); - } else { + if ($this->keyType === KeyType::MULTIPLE || \is_array($key)) { return $this->getMultiple($key); } + + return $this->getSingle($key); } /** @@ -233,7 +233,9 @@ final class MultiMap implements \Countable } } - return isset($this->keys[$key]) ? $this->values[$this->keys[$key]] ?? null : null; + return !\is_array($key) && isset($this->keys[$key]) + ? $this->values[$this->keys[$key]] ?? null + : null; } /** @@ -248,7 +250,7 @@ final class MultiMap implements \Countable */ public function set(int|string|array $key, mixed $value) : bool { - if ($this->keyType === KeyType::MULTIPLE && \is_array($key)) { + if ($this->keyType === KeyType::MULTIPLE || \is_array($key)) { return $this->setMultiple($key, $value); } @@ -267,6 +269,8 @@ final class MultiMap implements \Countable */ private function setMultiple(int|string|array $key, mixed $value) : bool { + $key = \is_array($key) ? $key : [$key]; + if ($this->orderType !== OrderType::STRICT) { /** @var array $permutation */ $permutation = Permutation::permut($key, [], false); @@ -315,7 +319,7 @@ final class MultiMap implements \Countable */ public function remove(int|string|array $key) : bool { - if ($this->keyType === KeyType::MULTIPLE && \is_array($key)) { + if ($this->keyType === KeyType::MULTIPLE || \is_array($key)) { return $this->removeMultiple($key); } @@ -333,6 +337,8 @@ final class MultiMap implements \Countable */ private function removeMultiple(int|string|array $key) : bool { + $key = \is_array($key) ? $key : [$key]; + if ($this->orderType !== OrderType::LOOSE) { return $this->remove(\implode(':', $key)); } @@ -381,14 +387,14 @@ final class MultiMap implements \Countable * * Both keys need to exist in the multimap. * - * @param int|string|array $old Old key - * @param int|string|array $new New key + * @param int|string $old Old key + * @param int|string $new New key * * @return bool * * @since 1.0.0 */ - public function remap(int|string|array $old, int|string|array $new) : bool + public function remap(int|string $old, int|string $new) : bool { if ($this->keyType === KeyType::MULTIPLE) { return false; @@ -410,13 +416,13 @@ final class MultiMap implements \Countable * * This only removes the value if no other key exists for this value. * - * @param int|string|array $key Key used to identify value + * @param int|string $key Key used to identify value * * @return bool * * @since 1.0.0 */ - public function removeKey(int|string|array $key) : bool + public function removeKey(int|string $key) : bool { if ($this->keyType === KeyType::MULTIPLE) { return false; @@ -460,7 +466,7 @@ final class MultiMap implements \Countable */ public function getSiblings(int|string|array $key) : array { - if ($this->keyType === KeyType::MULTIPLE) { + if ($this->keyType === KeyType::MULTIPLE || \is_array($key)) { return $this->getSiblingsMultiple($key); } diff --git a/System/File/Ftp/Directory.php b/System/File/Ftp/Directory.php index ccea449e4..09a7dbc05 100644 --- a/System/File/Ftp/Directory.php +++ b/System/File/Ftp/Directory.php @@ -673,15 +673,14 @@ class Directory extends FileAbstract implements DirectoryInterface /** * {@inheritdoc} */ - public function current() : FileAbstract + public function current() : ContainerInterface { $current = \current($this->nodes); - - if (isset($current) && $current instanceof self) { + if ($current instanceof self) { $current->index(); } - return $current; + return $current === false ? $this : $current; } /** @@ -698,12 +697,9 @@ class Directory extends FileAbstract implements DirectoryInterface public function next() { $next = \next($this->nodes); - - if (isset($next) && $next instanceof self) { + if ($next instanceof self) { $next->index(); } - - return $next; } /** diff --git a/System/File/Local/Directory.php b/System/File/Local/Directory.php index d6cfa5323..b598d3871 100644 --- a/System/File/Local/Directory.php +++ b/System/File/Local/Directory.php @@ -496,15 +496,14 @@ final class Directory extends FileAbstract implements DirectoryInterface /** * {@inheritdoc} */ - public function current() : FileAbstract + public function current() : ContainerInterface { $current = \current($this->nodes); - - if (isset($current) && $current instanceof self) { + if ($current instanceof self) { $current->index(); } - return $current; + return $current === false ? $this : $current; } /** @@ -521,12 +520,9 @@ final class Directory extends FileAbstract implements DirectoryInterface public function next() { $next = \next($this->nodes); - - if (isset($next) && $next instanceof self) { + if ($next instanceof self) { $next->index(); } - - return $next; } /** diff --git a/System/SystemUtils.php b/System/SystemUtils.php index 6392b32be..4eb487be7 100644 --- a/System/SystemUtils.php +++ b/System/SystemUtils.php @@ -85,7 +85,7 @@ final class SystemUtils if (\stristr(\PHP_OS, 'LINUX')) { $free = \shell_exec('free'); - if ($free === null) { + if ($free === null || $free === false) { return $memUsage; // @codeCoverageIgnore } @@ -115,7 +115,13 @@ final class SystemUtils \exec('wmic cpu get LoadPercentage', $cpuUsage); $cpuUsage = $cpuUsage[1]; } elseif (\stristr(\PHP_OS, 'LINUX') !== false) { - $cpuUsage = \sys_getloadavg()[0] * 100 / \exec('nproc'); + $loadavg = \sys_getloadavg(); + + if ($loadavg === false) { + return -1; + } + + $cpuUsage = $loadavg[0] * 100 / \exec('nproc'); } return (int) $cpuUsage; diff --git a/Utils/Barcode/C128Abstract.php b/Utils/Barcode/C128Abstract.php index 1df9f30f1..39169ec94 100644 --- a/Utils/Barcode/C128Abstract.php +++ b/Utils/Barcode/C128Abstract.php @@ -334,6 +334,11 @@ abstract class C128Abstract $white = \imagecolorallocate($image, 255, 255, 255); $location = 0; $length = \strlen($codeString); + + if ($white === false || $black === false) { + throw new \Exception(); // @codeCoverageIgnore + } + \imagefill($image, 0, 0, $white); for ($position = 1; $position <= $length; ++$position) { diff --git a/Utils/Encoding/Huffman/Huffman.php b/Utils/Encoding/Huffman/Huffman.php index 28cef0b52..c81b04111 100644 --- a/Utils/Encoding/Huffman/Huffman.php +++ b/Utils/Encoding/Huffman/Huffman.php @@ -94,7 +94,7 @@ final class Huffman $c .= '0'; } - $binary .= \chr(\bindec($c)); + $binary .= \chr((int) \bindec($c)); } return $binary; diff --git a/Utils/Git/Repository.php b/Utils/Git/Repository.php index 257446b9c..0c89aaf87 100644 --- a/Utils/Git/Repository.php +++ b/Utils/Git/Repository.php @@ -129,6 +129,11 @@ class Repository { $branches = $this->getBranches(); $active = \preg_grep('/^\*/', $branches); + + if (!\is_array($active)) { + return new Branch(); + } + \reset($active); return new Branch(\current($active)); diff --git a/Utils/IO/Zip/Gz.php b/Utils/IO/Zip/Gz.php index d36ff6e12..1f0e39de0 100644 --- a/Utils/IO/Zip/Gz.php +++ b/Utils/IO/Zip/Gz.php @@ -32,7 +32,11 @@ class Gz implements ArchiveInterface public static function pack(string|array $source, string $destination, bool $overwrite = false) : bool { $destination = \str_replace('\\', '/', $destination); - if (!$overwrite && \is_file($destination) || !\is_file($source)) { + if ($destination === false + || \is_array($source) + || (!$overwrite && \is_file($destination)) + || !\is_file($source) + ) { return false; } @@ -68,8 +72,8 @@ class Gz implements ArchiveInterface return false; // @codeCoverageIgnore } - while (!\gzeof($gz)) { - \fwrite($dest, \gzread($gz, 4096)); + while (!\gzeof($gz) && ($read = \gzread($gz, 4096)) !== false) { + \fwrite($dest, $read); } \fclose($dest); diff --git a/Utils/IO/Zip/Tar.php b/Utils/IO/Zip/Tar.php index bce5973e9..b8c5d2c37 100644 --- a/Utils/IO/Zip/Tar.php +++ b/Utils/IO/Zip/Tar.php @@ -34,11 +34,14 @@ class Tar implements ArchiveInterface public static function pack(string|array $sources, string $destination, bool $overwrite = false) : bool { $destination = FileUtils::absolute(\str_replace('\\', '/', $destination)); - if (!$overwrite && \is_file($destination)) { return false; } + if (\is_string($sources)) { + $sources = [$sources]; + } + $tar = new \PharData($destination); /** diff --git a/Utils/IO/Zip/Zip.php b/Utils/IO/Zip/Zip.php index c6a82bed5..2319c45d5 100644 --- a/Utils/IO/Zip/Zip.php +++ b/Utils/IO/Zip/Zip.php @@ -34,7 +34,6 @@ class Zip implements ArchiveInterface public static function pack(string|array $sources, string $destination, bool $overwrite = false) : bool { $destination = FileUtils::absolute(\str_replace('\\', '/', $destination)); - if (!$overwrite && \is_file($destination) || \is_dir($destination) ) { @@ -46,6 +45,10 @@ class Zip implements ArchiveInterface return false; } + if (\is_string($sources)) { + $sources = [$sources]; + } + /** * @var string $relative */ diff --git a/Utils/StringUtils.php b/Utils/StringUtils.php index d1878bdf1..9f2647da6 100644 --- a/Utils/StringUtils.php +++ b/Utils/StringUtils.php @@ -169,10 +169,13 @@ final class StringUtils */ public static function entropy(string $value) : float { - $entropy = 0.0; - $size = \strlen($value); + $entropy = 0.0; + $size = \strlen($value); + + /** @var array $countChars */ $countChars = \count_chars($value, 1); + /** @var int $v */ foreach ($countChars as $v) { $p = $v / $size; $entropy -= $p * \log($p) / \log(2); diff --git a/composer.json b/composer.json index 219d7edc5..1fdf69d84 100644 --- a/composer.json +++ b/composer.json @@ -8,11 +8,11 @@ } ], "require-dev": { - "phpunit/phpunit": "^9.4", - "squizlabs/php_codesniffer": "^3.5", - "phpmd/phpmd": "^2.9", - "phpstan/phpstan": "^0.12.58", - "phan/phan": "^3.2.6" + "phpunit/phpunit": ">=9.4", + "squizlabs/php_codesniffer": ">=3.5", + "phpmd/phpmd": ">=2.9", + "phpstan/phpstan": ">=0.12.58", + "phan/phan": ">=3.2.6" }, "minimum-stability": "dev", "prefer-stable": true diff --git a/composer.lock b/composer.lock index 0cd83bbd7..d1ec6a8fb 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": "22715ac88b295c37cc59c478717fddc1", + "content-hash": "48ce3426afe10bc3f79630f240946db1", "packages": [], "packages-dev": [ {