diff --git a/Build/phpstan/phpstan-baseline.neon b/Build/phpstan/phpstan-baseline.neon index 3ddbbb5d046497e29fae2295a2408a6aaa1d9521..32ba6b62735911bd706e97dc509989a828b11a6b 100644 --- a/Build/phpstan/phpstan-baseline.neon +++ b/Build/phpstan/phpstan-baseline.neon @@ -625,11 +625,6 @@ parameters: count: 1 path: ../../typo3/sysext/core/Classes/Http/NormalizedParams.php - - - message: "#^Result of && is always false\\.$#" - count: 1 - path: ../../typo3/sysext/core/Classes/Http/RedirectResponse.php - - message: "#^Call to function is_resource\\(\\) with Psr\\\\Http\\\\Message\\\\StreamInterface will always evaluate to false\\.$#" count: 1 @@ -645,11 +640,6 @@ parameters: count: 1 path: ../../typo3/sysext/core/Classes/Http/SelfEmittableLazyOpenStream.php - - - message: "#^Result of && is always false\\.$#" - count: 2 - path: ../../typo3/sysext/core/Classes/Http/UploadedFile.php - - message: "#^If condition is always true\\.$#" count: 9 @@ -1375,11 +1365,6 @@ parameters: count: 1 path: ../../typo3/sysext/core/Tests/Unit/Http/StreamTest.php - - - message: "#^Parameter \\#1 \\$port of method TYPO3\\\\CMS\\\\Core\\\\Http\\\\Uri\\:\\:withPort\\(\\) expects int\\|null, true given\\.$#" - count: 1 - path: ../../typo3/sysext/core/Tests/Unit/Http/UriTest.php - - message: "#^Parameter \\#1 \\$data of method TYPO3\\\\CMS\\\\Core\\\\LinkHandling\\\\EmailLinkHandler\\:\\:resolveHandlerData\\(\\) expects array, string given\\.$#" count: 1 diff --git a/composer.json b/composer.json index 96e8c8ec7acc49baf9aace0a29fb8d2196c922ae..4c576fca172d035838bb1cb0c73b87dcba4eb671 100644 --- a/composer.json +++ b/composer.json @@ -60,7 +60,7 @@ "firebase/php-jwt": "^6.3.1", "guzzlehttp/guzzle": "^7.5.0", "guzzlehttp/promises": "^1.5.2", - "guzzlehttp/psr7": "^2.4.3", + "guzzlehttp/psr7": "^2.5.0", "lolli42/finediff": "^1.0.2", "masterminds/html5": "^2.7.6", "nikic/php-parser": "^4.15.1", @@ -70,7 +70,7 @@ "psr/event-dispatcher": "^1.0", "psr/http-client": "^1.0", "psr/http-factory": "^1.0", - "psr/http-message": "^1.0", + "psr/http-message": "^1.1 || ^2.0", "psr/http-server-handler": "^1.0", "psr/http-server-middleware": "^1.0", "psr/log": "^2.0 || ^3.0", diff --git a/composer.lock b/composer.lock index d98de7ac8d975b9d0605b63dae6da0821c7ad022..a12cddf0d35ea7f665c84467669cd512a0b42cf7 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": "678bd9f11f60ea15357d52fdd6218528", + "content-hash": "fa6786dae7c5f8f41dfa2c7f37f3b2a6", "packages": [ { "name": "bacon/bacon-qr-code", @@ -1116,22 +1116,22 @@ }, { "name": "guzzlehttp/psr7", - "version": "2.4.3", + "version": "2.5.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "67c26b443f348a51926030c83481b85718457d3d" + "reference": "b635f279edd83fc275f822a1188157ffea568ff6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/67c26b443f348a51926030c83481b85718457d3d", - "reference": "67c26b443f348a51926030c83481b85718457d3d", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/b635f279edd83fc275f822a1188157ffea568ff6", + "reference": "b635f279edd83fc275f822a1188157ffea568ff6", "shasum": "" }, "require": { "php": "^7.2.5 || ^8.0", "psr/http-factory": "^1.0", - "psr/http-message": "^1.0", + "psr/http-message": "^1.1 || ^2.0", "ralouphie/getallheaders": "^3.0" }, "provide": { @@ -1151,9 +1151,6 @@ "bamarni-bin": { "bin-links": true, "forward-command": false - }, - "branch-alias": { - "dev-master": "2.4-dev" } }, "autoload": { @@ -1215,7 +1212,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.4.3" + "source": "https://github.com/guzzle/psr7/tree/2.5.0" }, "funding": [ { @@ -1231,7 +1228,7 @@ "type": "tidelift" } ], - "time": "2022-10-26T14:07:24+00:00" + "time": "2023-04-17T16:11:26+00:00" }, { "name": "lolli42/finediff", @@ -1737,21 +1734,21 @@ }, { "name": "psr/http-client", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/http-client.git", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" + "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/0955afe48220520692d2d09f7ab7e0f93ffd6a31", + "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31", "shasum": "" }, "require": { "php": "^7.0 || ^8.0", - "psr/http-message": "^1.0" + "psr/http-message": "^1.0 || ^2.0" }, "type": "library", "extra": { @@ -1771,7 +1768,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for HTTP clients", @@ -1783,27 +1780,27 @@ "psr-18" ], "support": { - "source": "https://github.com/php-fig/http-client/tree/master" + "source": "https://github.com/php-fig/http-client/tree/1.0.2" }, - "time": "2020-06-29T06:28:15+00:00" + "time": "2023-04-10T20:12:12+00:00" }, { "name": "psr/http-factory", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/http-factory.git", - "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" + "reference": "e616d01114759c4c489f93b099585439f795fe35" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", - "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", + "reference": "e616d01114759c4c489f93b099585439f795fe35", "shasum": "" }, "require": { "php": ">=7.0.0", - "psr/http-message": "^1.0" + "psr/http-message": "^1.0 || ^2.0" }, "type": "library", "extra": { @@ -1823,7 +1820,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interfaces for PSR-7 HTTP message factories", @@ -1838,31 +1835,31 @@ "response" ], "support": { - "source": "https://github.com/php-fig/http-factory/tree/master" + "source": "https://github.com/php-fig/http-factory/tree/1.0.2" }, - "time": "2019-04-30T12:38:16+00:00" + "time": "2023-04-10T20:10:41+00:00" }, { "name": "psr/http-message", - "version": "1.0.1", + "version": "2.0", "source": { "type": "git", "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -1877,7 +1874,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for HTTP messages", @@ -1891,27 +1888,27 @@ "response" ], "support": { - "source": "https://github.com/php-fig/http-message/tree/master" + "source": "https://github.com/php-fig/http-message/tree/2.0" }, - "time": "2016-08-06T14:39:51+00:00" + "time": "2023-04-04T09:54:51+00:00" }, { "name": "psr/http-server-handler", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/http-server-handler.git", - "reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7" + "reference": "84c4fb66179be4caaf8e97bd239203245302e7d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/aff2f80e33b7f026ec96bb42f63242dc50ffcae7", - "reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7", + "url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/84c4fb66179be4caaf8e97bd239203245302e7d4", + "reference": "84c4fb66179be4caaf8e97bd239203245302e7d4", "shasum": "" }, "require": { "php": ">=7.0", - "psr/http-message": "^1.0" + "psr/http-message": "^1.0 || ^2.0" }, "type": "library", "extra": { @@ -1931,7 +1928,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for HTTP server-side request handler", @@ -1947,28 +1944,27 @@ "server" ], "support": { - "issues": "https://github.com/php-fig/http-server-handler/issues", - "source": "https://github.com/php-fig/http-server-handler/tree/master" + "source": "https://github.com/php-fig/http-server-handler/tree/1.0.2" }, - "time": "2018-10-30T16:46:14+00:00" + "time": "2023-04-10T20:06:20+00:00" }, { "name": "psr/http-server-middleware", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/http-server-middleware.git", - "reference": "2296f45510945530b9dceb8bcedb5cb84d40c5f5" + "reference": "c1481f747daaa6a0782775cd6a8c26a1bf4a3829" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-server-middleware/zipball/2296f45510945530b9dceb8bcedb5cb84d40c5f5", - "reference": "2296f45510945530b9dceb8bcedb5cb84d40c5f5", + "url": "https://api.github.com/repos/php-fig/http-server-middleware/zipball/c1481f747daaa6a0782775cd6a8c26a1bf4a3829", + "reference": "c1481f747daaa6a0782775cd6a8c26a1bf4a3829", "shasum": "" }, "require": { "php": ">=7.0", - "psr/http-message": "^1.0", + "psr/http-message": "^1.0 || ^2.0", "psr/http-server-handler": "^1.0" }, "type": "library", @@ -1989,7 +1985,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for HTTP server-side middleware", @@ -2005,9 +2001,9 @@ ], "support": { "issues": "https://github.com/php-fig/http-server-middleware/issues", - "source": "https://github.com/php-fig/http-server-middleware/tree/master" + "source": "https://github.com/php-fig/http-server-middleware/tree/1.0.2" }, - "time": "2018-10-30T17:12:04+00:00" + "time": "2023-04-11T06:14:47+00:00" }, { "name": "psr/log", diff --git a/typo3/sysext/adminpanel/composer.json b/typo3/sysext/adminpanel/composer.json index bbb700e8b6620518f393493d0190d5597ea5193d..c8b8cf62a29b93a0a9e712c390d06516237b6212 100644 --- a/typo3/sysext/adminpanel/composer.json +++ b/typo3/sysext/adminpanel/composer.json @@ -19,7 +19,7 @@ "sort-packages": true }, "require": { - "psr/http-message": "^1.0", + "psr/http-message": "^1.1 || ^2.0", "psr/http-server-handler": "^1.0", "psr/http-server-middleware": "^1.0", "symfony/var-dumper": "^6.2", diff --git a/typo3/sysext/core/Classes/Http/FalDumpFileContentsDecoratorStream.php b/typo3/sysext/core/Classes/Http/FalDumpFileContentsDecoratorStream.php index bba6c4b65604c47d386956d83f0093cf13065f8a..dc7ef6ea0f226d3851b18858b2904b8d93c976a3 100644 --- a/typo3/sysext/core/Classes/Http/FalDumpFileContentsDecoratorStream.php +++ b/typo3/sysext/core/Classes/Http/FalDumpFileContentsDecoratorStream.php @@ -33,26 +33,11 @@ class FalDumpFileContentsDecoratorStream implements StreamInterface, SelfEmittab { use StreamDecoratorTrait; - /** - * @var string - */ - protected $identifier; - - /** - * @var DriverInterface - */ - protected $driver; - - /** - * @var int - */ - protected $size; - - public function __construct(string $identifier, DriverInterface $driver, int $size) - { - $this->identifier = $identifier; - $this->driver = $driver; - $this->size = $size; + public function __construct( + protected readonly string $identifier, + protected readonly DriverInterface $driver, + protected readonly int $size + ) { } /** @@ -86,10 +71,9 @@ class FalDumpFileContentsDecoratorStream implements StreamInterface, SelfEmittab } /** - * @param string $string - * @throws \RuntimeException on failure. + * @throws \RuntimeException */ - public function write($string) + public function write(string $string): int { throw new \RuntimeException('Cannot write to a ' . self::class, 1538331852); } diff --git a/typo3/sysext/core/Classes/Http/HtmlResponse.php b/typo3/sysext/core/Classes/Http/HtmlResponse.php index e2ee186f611f3ccd97c5d6b904b41fc3df240fab..71ec3dd70bfbfc14553856625a17b8b22c7d84ce 100644 --- a/typo3/sysext/core/Classes/Http/HtmlResponse.php +++ b/typo3/sysext/core/Classes/Http/HtmlResponse.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /* * This file is part of the TYPO3 CMS project. * @@ -31,7 +33,7 @@ class HtmlResponse extends Response * @param int $status status code for the response; defaults to 200. * @param array $headers Additional headers to be set. */ - public function __construct($content, $status = 200, array $headers = []) + public function __construct(string $content, int $status = 200, array $headers = []) { $body = new Stream('php://temp', 'wb+'); $body->write($content); diff --git a/typo3/sysext/core/Classes/Http/Message.php b/typo3/sysext/core/Classes/Http/Message.php index 1e497250908ae5739e939d06aefb159858c0e3d7..43c05ab145807179e6842b5f0e0f1809c852bbf0 100644 --- a/typo3/sysext/core/Classes/Http/Message.php +++ b/typo3/sysext/core/Classes/Http/Message.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /* * This file is part of the TYPO3 CMS project. * @@ -30,29 +32,25 @@ class Message implements MessageInterface { /** * The HTTP Protocol version, defaults to 1.1 - * @var string */ - protected $protocolVersion = '1.1'; + protected string $protocolVersion = '1.1'; /** * Associative array containing all headers of this Message * This is a mixed-case list of the headers (as due to the specification) - * @var array */ - protected $headers = []; + protected array $headers = []; /** * Lowercased version of all headers, in order to check if a header is set or not * this way a lot of checks are easier to be set - * @var array */ - protected $lowercasedHeaderNames = []; + protected array $lowercasedHeaderNames = []; /** * The body as a Stream object - * @var StreamInterface|null */ - protected $body; + protected ?StreamInterface $body = null; /** * Retrieves the HTTP protocol version as a string. @@ -61,7 +59,7 @@ class Message implements MessageInterface * * @return string HTTP protocol version. */ - public function getProtocolVersion() + public function getProtocolVersion(): string { return $this->protocolVersion; } @@ -79,7 +77,7 @@ class Message implements MessageInterface * @param string $version HTTP protocol version * @return static */ - public function withProtocolVersion($version) + public function withProtocolVersion(string $version): MessageInterface { $clonedObject = clone $this; $clonedObject->protocolVersion = $version; @@ -113,7 +111,7 @@ class Message implements MessageInterface * key MUST be a header name, and each value MUST be an array of strings * for that header. */ - public function getHeaders() + public function getHeaders(): array { return $this->headers; } @@ -126,7 +124,7 @@ class Message implements MessageInterface * name using a case-insensitive string comparison. Returns false if * no matching header name is found in the message. */ - public function hasHeader($name) + public function hasHeader(string $name): bool { return isset($this->lowercasedHeaderNames[strtolower($name)]); } @@ -145,7 +143,7 @@ class Message implements MessageInterface * header. If the header does not appear in the message, this method MUST * return an empty array. */ - public function getHeader($name) + public function getHeader(string $name): array { if (!$this->hasHeader($name)) { return []; @@ -177,7 +175,7 @@ class Message implements MessageInterface * concatenated together using a comma. If the header does not appear in * the message, this method MUST return an empty string. */ - public function getHeaderLine($name) + public function getHeaderLine(string $name): string { $headerValue = $this->getHeader($name); if (empty($headerValue)) { @@ -201,7 +199,7 @@ class Message implements MessageInterface * @return static * @throws \InvalidArgumentException for invalid header names or values. */ - public function withHeader($name, $value) + public function withHeader(string $name, $value): MessageInterface { if (is_string($value)) { $value = [$value]; @@ -237,7 +235,7 @@ class Message implements MessageInterface * @return static * @throws \InvalidArgumentException for invalid header names or values. */ - public function withAddedHeader($name, $value) + public function withAddedHeader(string $name, $value): MessageInterface { if (is_string($value)) { $value = [$value]; @@ -268,7 +266,7 @@ class Message implements MessageInterface * @param string $name Case-insensitive header field name to remove. * @return static */ - public function withoutHeader($name) + public function withoutHeader(string $name): MessageInterface { if (!$this->hasHeader($name)) { return clone $this; @@ -284,9 +282,9 @@ class Message implements MessageInterface /** * Gets the body of the message. * - * @return \Psr\Http\Message\StreamInterface Returns the body as a stream. + * @return StreamInterface Returns the body as a stream. */ - public function getBody() + public function getBody(): StreamInterface { if ($this->body === null) { $this->body = new Stream('php://temp', 'r+'); @@ -303,11 +301,10 @@ class Message implements MessageInterface * immutability of the message, and MUST return a new instance that has the * new body stream. * - * @param \Psr\Http\Message\StreamInterface $body Body. * @return static * @throws \InvalidArgumentException When the body is not valid. */ - public function withBody(StreamInterface $body) + public function withBody(StreamInterface $body): MessageInterface { $clonedObject = clone $this; $clonedObject->body = $body; @@ -319,7 +316,7 @@ class Message implements MessageInterface * * @throws \InvalidArgumentException */ - protected function assertHeaders(array $headers) + protected function assertHeaders(array $headers): void { foreach ($headers as $name => $headerValues) { $this->validateHeaderName($name); @@ -340,7 +337,7 @@ class Message implements MessageInterface * @param array $originalHeaders Headers to filter. * @return array Filtered headers and names. */ - protected function filterHeaders(array $originalHeaders) + protected function filterHeaders(array $originalHeaders): array { $headerNames = $headers = []; foreach ($originalHeaders as $header => $value) { @@ -358,10 +355,8 @@ class Message implements MessageInterface /** * Helper function to test if an array contains only strings - * - * @return bool */ - protected function arrayContainsOnlyStrings(array $data) + protected function arrayContainsOnlyStrings(array $data): bool { return array_reduce($data, static function ($original, $item) { return is_string($item) ? $original : false; @@ -375,7 +370,7 @@ class Message implements MessageInterface * @param string[] $values * @throws \InvalidArgumentException */ - protected function validateHeaderValues(array $values) + protected function validateHeaderValues(array $values): void { array_walk($values, static function ($value, $key, Message $messageObject) { if (!$messageObject->isValidHeaderValue($value)) { @@ -397,12 +392,10 @@ class Message implements MessageInterface * lossy. * * @see http://en.wikipedia.org/wiki/HTTP_response_splitting - * @param string $value - * @return string + * @todo: Unused? And why is this public? Maybe align with zend-diactoros again */ - public function filter($value) + public function filter(string $value): string { - $value = (string)$value; $length = strlen($value); $string = ''; for ($i = 0; $i < $length; $i += 1) { @@ -435,13 +428,13 @@ class Message implements MessageInterface } /** - * Check whether or not a header name is valid and throw an exception. + * Check whether a header name is valid and throw an exception. * * @see https://tools.ietf.org/html/rfc7230#section-3.2 - * @param string $name * @throws \InvalidArgumentException + * @todo: Review. Should be protected / private, maybe align with zend-diactoros again */ - public function validateHeaderName($name) + public function validateHeaderName(string $name): void { if (!preg_match('/^[a-zA-Z0-9\'`#$%&*+.^_|~!-]+$/', $name)) { throw new \InvalidArgumentException('Invalid header name, given "' . $name . '"', 1436717270); @@ -456,13 +449,10 @@ class Message implements MessageInterface * a single CRLF sequence followed by a space or horizontal tab. * * @see http://en.wikipedia.org/wiki/HTTP_response_splitting - * @param string $value - * @return bool + * @todo: Review. Should be protected / private, maybe align with zend-diactoros again */ - public function isValidHeaderValue($value) + public function isValidHeaderValue(string $value): bool { - $value = (string)$value; - // Any occurrence of \r or \n is invalid if (strpbrk($value, "\r\n") !== false) { return false; diff --git a/typo3/sysext/core/Classes/Http/RedirectResponse.php b/typo3/sysext/core/Classes/Http/RedirectResponse.php index 52ab5022af8f90b0fe2723ac8c4158529ee43933..a256ec02c959d5591d7d8c899df7e974ddbd2ca5 100644 --- a/typo3/sysext/core/Classes/Http/RedirectResponse.php +++ b/typo3/sysext/core/Classes/Http/RedirectResponse.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /* * This file is part of the TYPO3 CMS project. * @@ -34,14 +36,8 @@ class RedirectResponse extends Response * @param int $status status code for the redirect; defaults to 302. * @param array $headers Additional headers to be set. */ - public function __construct($uri, $status = 302, array $headers = []) + public function __construct(string|UriInterface $uri, int $status = 302, array $headers = []) { - if (!is_string($uri) && !($uri instanceof UriInterface)) { - throw new \InvalidArgumentException( - 'The given uri be a string or UriInterface - ' . get_debug_type($uri) . ' given', - 1504814459 - ); - } $headers['location'] = [(string)$uri]; parent::__construct('php://temp', $status, $headers); } diff --git a/typo3/sysext/core/Classes/Http/Request.php b/typo3/sysext/core/Classes/Http/Request.php index 2994aeee539e008d0ac1d4f8fa1b21768a7a7314..47ac172bacf92e42b8838e580eef903858a0b8fb 100644 --- a/typo3/sysext/core/Classes/Http/Request.php +++ b/typo3/sysext/core/Classes/Http/Request.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /* * This file is part of the TYPO3 CMS project. * @@ -107,7 +109,7 @@ class Request extends Message implements RequestInterface $this->validateMethod($method); $this->method = $method; - $this->uri = $uri; + $this->uri = $uri; [$this->lowercasedHeaderNames, $headers] = $this->filterHeaders($headers); $this->assertHeaders($headers); $this->headers = $headers; @@ -158,17 +160,17 @@ class Request extends Message implements RequestInterface * If the header does not appear in the message, this method MUST return an * empty array. * - * @param string $header Case-insensitive header field name. + * @param string $name Case-insensitive header field name. * @return string[] An array of string values as provided for the given * header. If the header does not appear in the message, this method MUST * return an empty array. */ - public function getHeader($header): array + public function getHeader(string $name): array { - if (!$this->hasHeader($header) && strtolower($header) === 'host' && ($this->uri?->getHost())) { + if (!$this->hasHeader($name) && strtolower($name) === 'host' && ($this->uri?->getHost())) { return [$this->getHostFromUri()]; } - return parent::getHeader($header); + return parent::getHeader($name); } /** @@ -264,7 +266,7 @@ class Request extends Message implements RequestInterface * @param string $method Case-sensitive method. * @throws \InvalidArgumentException for invalid HTTP methods. */ - public function withMethod($method): static + public function withMethod(string $method): static { $clonedObject = clone $this; $clonedObject->method = $method; @@ -276,14 +278,11 @@ class Request extends Message implements RequestInterface * * This method MUST return a UriInterface instance. * - * @todo This method currently may return null instead. This is - * a PSR-7 spec violation that should be corrected. - * * @link https://tools.ietf.org/html/rfc3986#section-4.3 - * @return \Psr\Http\Message\UriInterface|null Returns a UriInterface instance + * @return UriInterface Returns a UriInterface instance * representing the URI of the request. */ - public function getUri(): ?UriInterface + public function getUri(): UriInterface { return $this->uri; } @@ -315,10 +314,10 @@ class Request extends Message implements RequestInterface * * @link https://tools.ietf.org/html/rfc3986#section-4.3 * - * @param \Psr\Http\Message\UriInterface $uri New request URI to use. + * @param UriInterface $uri New request URI to use. * @param bool $preserveHost Preserve the original state of the Host header. */ - public function withUri(UriInterface $uri, $preserveHost = false): static + public function withUri(UriInterface $uri, bool $preserveHost = false): static { $clonedObject = clone $this; $clonedObject->uri = $uri; diff --git a/typo3/sysext/core/Classes/Http/Response.php b/typo3/sysext/core/Classes/Http/Response.php index 3e029f58de377db6dd419ae17310346bdf25108d..57893b27b90629eb75e262186db5733b6ed2e591 100644 --- a/typo3/sysext/core/Classes/Http/Response.php +++ b/typo3/sysext/core/Classes/Http/Response.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /* * This file is part of the TYPO3 CMS project. * @@ -30,21 +32,19 @@ class Response extends Message implements ResponseInterface { /** * The HTTP status code of the response - * @var int $statusCode */ - protected $statusCode; + protected int $statusCode; /** * The reason phrase of the response - * @var string $reasonPhrase */ - protected $reasonPhrase = ''; + protected string $reasonPhrase = ''; /** * The standardized and other important HTTP Status Codes * @var array */ - protected $availableStatusCodes = [ + protected array $availableStatusCodes = [ // INFORMATIONAL CODES 100 => 'Continue', 101 => 'Switching Protocols', @@ -120,11 +120,9 @@ class Response extends Message implements ResponseInterface * Constructor for generating new responses * * @param StreamInterface|string|null $body - * @param int $statusCode - * @param array $headers * @throws \InvalidArgumentException if any of the given arguments are given */ - public function __construct($body = 'php://temp', $statusCode = 200, $headers = [], string $reasonPhrase = '') + public function __construct($body = 'php://temp', int $statusCode = 200, array $headers = [], string $reasonPhrase = '') { // Build a streamable object for the body if ($body !== null && !is_string($body) && !is_resource($body) && !$body instanceof StreamInterface) { @@ -139,7 +137,7 @@ class Response extends Message implements ResponseInterface if (MathUtility::canBeInterpretedAsInteger($statusCode) === false || !array_key_exists((int)$statusCode, $this->availableStatusCodes)) { throw new \InvalidArgumentException('The given status code is not a valid HTTP status code.', 1436717278); } - $this->statusCode = (int)$statusCode; + $this->statusCode = $statusCode; $this->reasonPhrase = $reasonPhrase === '' ? $this->availableStatusCodes[$this->statusCode] : $reasonPhrase; [$this->lowercasedHeaderNames, $headers] = $this->filterHeaders($headers); @@ -155,7 +153,7 @@ class Response extends Message implements ResponseInterface * * @return int Status code. */ - public function getStatusCode() + public function getStatusCode(): int { return $this->statusCode; } @@ -181,9 +179,9 @@ class Response extends Message implements ResponseInterface * @return static * @throws \InvalidArgumentException For invalid status code arguments. */ - public function withStatus($code, $reasonPhrase = '') + public function withStatus(int $code, string $reasonPhrase = ''): ResponseInterface { - if (MathUtility::canBeInterpretedAsInteger($code) === false || !array_key_exists((int)$code, $this->availableStatusCodes)) { + if (!array_key_exists((int)$code, $this->availableStatusCodes)) { throw new \InvalidArgumentException('The given status code is not a valid HTTP status code', 1436717279); } $clonedObject = clone $this; @@ -205,7 +203,7 @@ class Response extends Message implements ResponseInterface * @link http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml * @return string Reason phrase; must return an empty string if none present. */ - public function getReasonPhrase() + public function getReasonPhrase(): string { return $this->reasonPhrase; } diff --git a/typo3/sysext/core/Classes/Http/SelfEmittableLazyOpenStream.php b/typo3/sysext/core/Classes/Http/SelfEmittableLazyOpenStream.php index 5fee7db34a35cdb10f550dfec023046703d67eff..6842199f2822d83fc832365a2a728eb6cbb1ab5c 100644 --- a/typo3/sysext/core/Classes/Http/SelfEmittableLazyOpenStream.php +++ b/typo3/sysext/core/Classes/Http/SelfEmittableLazyOpenStream.php @@ -31,18 +31,15 @@ use Psr\Http\Message\StreamInterface; class SelfEmittableLazyOpenStream implements SelfEmittableStreamInterface { use StreamDecoratorTrait; - protected string $filename; - protected LazyOpenStream $stream; + + protected readonly LazyOpenStream $stream; /** * Constructor setting up the PHP resource - * - * @param string $filename */ - public function __construct($filename) + public function __construct(protected readonly string $filename) { $this->stream = new LazyOpenStream($filename, 'r'); - $this->filename = $filename; } /** @@ -50,7 +47,7 @@ class SelfEmittableLazyOpenStream implements SelfEmittableStreamInterface */ public function emit() { - readfile($this->filename, false); + readfile($this->filename); } public function isWritable(): bool @@ -59,10 +56,9 @@ class SelfEmittableLazyOpenStream implements SelfEmittableStreamInterface } /** - * @param string $string * @throws \RuntimeException on failure. */ - public function write($string) + public function write(string $string): int { throw new \RuntimeException('Cannot write to a ' . self::class, 1538331833); } diff --git a/typo3/sysext/core/Classes/Http/ServerRequest.php b/typo3/sysext/core/Classes/Http/ServerRequest.php index 57565ffbde4553eabbf9fe9398061bb3d3e4e3b1..9124ec64ea0e426367d403b59ad31f9cc00a15c3 100644 --- a/typo3/sysext/core/Classes/Http/ServerRequest.php +++ b/typo3/sysext/core/Classes/Http/ServerRequest.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /* * This file is part of the TYPO3 CMS project. * @@ -35,36 +37,17 @@ use Psr\Http\Message\UriInterface; */ class ServerRequest extends Request implements ServerRequestInterface { - /** - * @var array - */ - protected $attributes = []; - - /** - * @var array - */ - protected $cookieParams = []; + protected array $attributes = []; + protected array $cookieParams = []; + protected array $queryParams = []; + protected array $serverParams = []; + protected array $uploadedFiles = []; /** * @var array|object|null */ protected $parsedBody; - /** - * @var array - */ - protected $queryParams = []; - - /** - * @var array - */ - protected $serverParams = []; - - /** - * @var array - */ - protected $uploadedFiles = []; - /** * Constructor, the only place to set all parameters of this Message/Request * @@ -73,10 +56,10 @@ class ServerRequest extends Request implements ServerRequestInterface * @param string|resource|StreamInterface|null $body Message body, if any. * @param array $headers Headers for the message, if any. * @param array $serverParams Server parameters, typically from $_SERVER - * @param array $uploadedFiles Upload file information, a tree of UploadedFiles + * @param array|null $uploadedFiles Upload file information, a tree of UploadedFiles * @throws \InvalidArgumentException for any invalid value. */ - public function __construct($uri = null, $method = null, $body = 'php://input', array $headers = [], array $serverParams = [], array $uploadedFiles = null) + public function __construct(string|UriInterface|null $uri = null, $method = null, $body = 'php://input', array $headers = [], array $serverParams = [], array $uploadedFiles = null) { if ($uploadedFiles !== null) { $this->validateUploadedFiles($uploadedFiles); @@ -84,7 +67,7 @@ class ServerRequest extends Request implements ServerRequestInterface parent::__construct($uri, $method ?? 'GET', $body, $headers); - $this->serverParams = $serverParams; + $this->serverParams = $serverParams; $this->uploadedFiles = $uploadedFiles ?? []; } @@ -94,10 +77,8 @@ class ServerRequest extends Request implements ServerRequestInterface * Retrieves data related to the incoming request environment, * typically derived from PHP's $_SERVER superglobal. The data IS NOT * REQUIRED to originate from $_SERVER. - * - * @return array */ - public function getServerParams() + public function getServerParams(): array { return $this->serverParams; } @@ -108,11 +89,9 @@ class ServerRequest extends Request implements ServerRequestInterface * Retrieves cookies sent by the client to the server. * * The data MUST be compatible with the structure of the $_COOKIE - * superglobal. - * - * @return array + * super global. */ - public function getCookieParams() + public function getCookieParams(): array { return $this->cookieParams; } @@ -134,7 +113,7 @@ class ServerRequest extends Request implements ServerRequestInterface * @param array $cookies Array of key/value pairs representing cookies. * @return static */ - public function withCookieParams(array $cookies) + public function withCookieParams(array $cookies): ServerRequestInterface { $clonedObject = clone $this; $clonedObject->cookieParams = $cookies; @@ -150,10 +129,8 @@ class ServerRequest extends Request implements ServerRequestInterface * params. If you need to ensure you are only getting the original * values, you may need to parse the query string from `getUri()->getQuery()` * or from the `QUERY_STRING` server param. - * - * @return array */ - public function getQueryParams() + public function getQueryParams(): array { return $this->queryParams; } @@ -180,7 +157,7 @@ class ServerRequest extends Request implements ServerRequestInterface * $_GET. * @return static */ - public function withQueryParams(array $query) + public function withQueryParams(array $query): ServerRequestInterface { $clonedObject = clone $this; $clonedObject->queryParams = $query; @@ -199,7 +176,7 @@ class ServerRequest extends Request implements ServerRequestInterface * @return array An array tree of UploadedFileInterface instances; an empty * array MUST be returned if no data is present. */ - public function getUploadedFiles() + public function getUploadedFiles(): array { return $this->uploadedFiles; } @@ -215,7 +192,7 @@ class ServerRequest extends Request implements ServerRequestInterface * @return static * @throws \InvalidArgumentException if an invalid structure is provided. */ - public function withUploadedFiles(array $uploadedFiles) + public function withUploadedFiles(array $uploadedFiles): ServerRequestInterface { $this->validateUploadedFiles($uploadedFiles); $clonedObject = clone $this; @@ -271,7 +248,7 @@ class ServerRequest extends Request implements ServerRequestInterface * @throws \InvalidArgumentException if an unsupported argument type is * provided. */ - public function withParsedBody($data) + public function withParsedBody($data): ServerRequestInterface { $clonedObject = clone $this; $clonedObject->parsedBody = $data; @@ -289,7 +266,7 @@ class ServerRequest extends Request implements ServerRequestInterface * * @return array Attributes derived from the request. */ - public function getAttributes() + public function getAttributes(): array { return $this->attributes; } @@ -310,7 +287,7 @@ class ServerRequest extends Request implements ServerRequestInterface * @param mixed $default Default value to return if the attribute does not exist. * @return mixed */ - public function getAttribute($name, $default = null) + public function getAttribute(string $name, $default = null) { return $this->attributes[$name] ?? $default; } @@ -331,7 +308,7 @@ class ServerRequest extends Request implements ServerRequestInterface * @param mixed $value The value of the attribute. * @return static */ - public function withAttribute($name, $value) + public function withAttribute(string $name, $value): ServerRequestInterface { $clonedObject = clone $this; $clonedObject->attributes[$name] = $value; @@ -353,7 +330,7 @@ class ServerRequest extends Request implements ServerRequestInterface * @param string $name The attribute name. * @return static */ - public function withoutAttribute($name) + public function withoutAttribute(string $name): ServerRequestInterface { $clonedObject = clone $this; if (!isset($clonedObject->attributes[$name])) { @@ -368,7 +345,7 @@ class ServerRequest extends Request implements ServerRequestInterface * * @throws \InvalidArgumentException if any leaf is not an UploadedFileInterface instance. */ - protected function validateUploadedFiles(array $uploadedFiles) + protected function validateUploadedFiles(array $uploadedFiles): void { foreach ($uploadedFiles as $file) { if (is_array($file)) { diff --git a/typo3/sysext/core/Classes/Http/Stream.php b/typo3/sysext/core/Classes/Http/Stream.php index 76e71014bbad8cb4b0610b5a0ebb3b11bde9bce6..5a97c0bdb4078f8df9bb4062f563ae88b0e21990 100644 --- a/typo3/sysext/core/Classes/Http/Stream.php +++ b/typo3/sysext/core/Classes/Http/Stream.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /* * This file is part of the TYPO3 CMS project. * @@ -45,7 +47,7 @@ class Stream implements StreamInterface * @param string $mode Mode with which to open stream * @throws \InvalidArgumentException */ - public function __construct($stream, $mode = 'r') + public function __construct($stream, string $mode = 'r') { $this->stream = $stream; if (is_resource($stream)) { @@ -71,7 +73,7 @@ class Stream implements StreamInterface * @see https://php.net/manual/en/language.oop5.magic.php#object.tostring * @return string */ - public function __toString() + public function __toString(): string { if (!$this->isReadable()) { return ''; @@ -87,7 +89,7 @@ class Stream implements StreamInterface /** * Closes the stream and any underlying resources. */ - public function close() + public function close(): void { if (!is_resource($this->resource)) { return; @@ -118,7 +120,7 @@ class Stream implements StreamInterface * * @return int|null Returns the size in bytes if known, or null if unknown. */ - public function getSize() + public function getSize(): ?int { if ($this->resource === null) { return null; @@ -133,7 +135,7 @@ class Stream implements StreamInterface * @return int Position of the file pointer * @throws \RuntimeException on error. */ - public function tell() + public function tell(): int { if (!is_resource($this->resource)) { throw new \RuntimeException('No resource available; cannot tell position', 1436717285); @@ -147,10 +149,8 @@ class Stream implements StreamInterface /** * Returns true if the stream is at the end of the stream. - * - * @return bool */ - public function eof() + public function eof(): bool { if (!is_resource($this->resource)) { return true; @@ -159,11 +159,9 @@ class Stream implements StreamInterface } /** - * Returns whether or not the stream is seekable. - * - * @return bool + * Returns whether the stream is seekable. */ - public function isSeekable() + public function isSeekable(): bool { if (!is_resource($this->resource)) { return false; @@ -185,7 +183,7 @@ class Stream implements StreamInterface * * @throws \RuntimeException on failure. */ - public function seek($offset, $whence = SEEK_SET) + public function seek(int $offset, int $whence = SEEK_SET): void { if (!is_resource($this->resource)) { throw new \RuntimeException('No resource available; cannot seek position', 1436717287); @@ -210,17 +208,15 @@ class Stream implements StreamInterface * @link http://www.php.net/manual/en/function.fseek.php * @throws \RuntimeException on failure. */ - public function rewind() + public function rewind(): void { $this->seek(0); } /** - * Returns whether or not the stream is writable. - * - * @return bool + * Returns whether the stream is writable. */ - public function isWritable() + public function isWritable(): bool { if (!is_resource($this->resource)) { return false; @@ -236,7 +232,7 @@ class Stream implements StreamInterface * @return int Returns the number of bytes written to the stream. * @throws \RuntimeException on failure. */ - public function write($string) + public function write(string $string): int { if (!is_resource($this->resource)) { throw new \RuntimeException('No resource available; cannot write', 1436717290); @@ -249,11 +245,9 @@ class Stream implements StreamInterface } /** - * Returns whether or not the stream is readable. - * - * @return bool + * Returns whether the stream is readable. */ - public function isReadable() + public function isReadable(): bool { if (!is_resource($this->resource)) { return false; @@ -272,7 +266,7 @@ class Stream implements StreamInterface * if no bytes are available. * @throws \RuntimeException if an error occurs. */ - public function read($length) + public function read(int $length): string { if (!is_resource($this->resource)) { throw new \RuntimeException('No resource available; cannot read', 1436717292); @@ -290,11 +284,9 @@ class Stream implements StreamInterface /** * Returns the remaining contents in a string * - * @return string - * @throws \RuntimeException if unable to read or an error occurs while - * reading. + * @throws \RuntimeException if unable to read or an error occurs while reading. */ - public function getContents() + public function getContents(): string { if (!is_resource($this->resource) || !$this->isReadable()) { return ''; @@ -320,7 +312,7 @@ class Stream implements StreamInterface * provided. Returns a specific key value if a key is provided and the * value is found, or null if the key is not found. */ - public function getMetadata($key = null) + public function getMetadata(?string $key = null) { if (!is_resource($this->resource)) { return null; @@ -343,7 +335,7 @@ class Stream implements StreamInterface * @throws \InvalidArgumentException for stream identifier that cannot be cast to a resource * @throws \InvalidArgumentException for non-resource stream */ - public function attach($resource, $mode = 'r') + public function attach($resource, string $mode = 'r') { $error = null; if (!is_resource($resource) && is_string($resource)) { diff --git a/typo3/sysext/core/Classes/Http/UploadedFile.php b/typo3/sysext/core/Classes/Http/UploadedFile.php index dee1717311f0f19cbde124e01668322fc7330325..6f1da82864f4cbd04d646326ab0551fd2845ab70 100644 --- a/typo3/sysext/core/Classes/Http/UploadedFile.php +++ b/typo3/sysext/core/Classes/Http/UploadedFile.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /* * This file is part of the TYPO3 CMS project. * @@ -30,40 +32,13 @@ use TYPO3\CMS\Core\Utility\GeneralUtility; */ class UploadedFile implements UploadedFileInterface { - /** - * @var string|null - */ - protected $file; - - /** - * @var StreamInterface|null - */ - protected $stream; - - /** - * @var string|null - */ - protected $clientFilename; - - /** - * @var string|null - */ - protected $clientMediaType; - - /** - * @var int - */ - protected $error; - - /** - * @var bool - */ - protected $moved = false; - - /** - * @var int - */ - protected $size; + protected ?string $file = null; + protected ?StreamInterface $stream = null; + protected ?string $clientFilename; + protected ?string $clientMediaType; + protected int $error; + protected bool $moved = false; + protected int $size; /** * Constructor method @@ -71,12 +46,12 @@ class UploadedFile implements UploadedFileInterface * @param string|resource|StreamInterface $input is either a stream or a filename * @param int $size see $_FILES['size'] from PHP * @param int $errorStatus see $_FILES['error'] - * @param string $clientFilename the original filename handed over from the client - * @param string $clientMediaType the media type (optional) + * @param string|null $clientFilename the original filename handed over from the client + * @param string|null $clientMediaType the media type (optional) * * @throws \InvalidArgumentException */ - public function __construct($input, $size, $errorStatus, $clientFilename = null, $clientMediaType = null) + public function __construct($input, int $size, int $errorStatus, ?string $clientFilename = null, ?string $clientMediaType = null) { if (is_string($input)) { $this->file = $input; @@ -92,24 +67,14 @@ class UploadedFile implements UploadedFileInterface throw new \InvalidArgumentException('The input given was not a valid stream or file.', 1436717301); } - if (!is_int($size)) { - throw new \InvalidArgumentException('The size provided for an uploaded file must be an integer.', 1436717302); - } $this->size = $size; - if (!is_int($errorStatus) || $errorStatus < 0 || $errorStatus > 8) { + if ($errorStatus < 0 || $errorStatus > 8) { throw new \InvalidArgumentException('Invalid error status for an uploaded file. See UPLOAD_ERR_* constant in PHP.', 1436717303); } $this->error = $errorStatus; - if ($clientFilename !== null && !is_string($clientFilename)) { - throw new \InvalidArgumentException('Invalid client filename provided for an uploaded file.', 1436717304); - } $this->clientFilename = $clientFilename; - - if ($clientMediaType !== null && !is_string($clientMediaType)) { - throw new \InvalidArgumentException('Invalid client media type provided for an uploaded file.', 1436717305); - } $this->clientMediaType = $clientMediaType; } @@ -125,7 +90,7 @@ class UploadedFile implements UploadedFileInterface * @return StreamInterface Stream representation of the uploaded file. * @throws \RuntimeException in cases when no stream is available or can be created. */ - public function getStream() + public function getStream(): StreamInterface { if ($this->moved) { throw new \RuntimeException('Cannot retrieve stream as it was moved.', 1436717306); @@ -170,9 +135,9 @@ class UploadedFile implements UploadedFileInterface * @throws \InvalidArgumentException if the $path specified is invalid. * @throws \RuntimeException on any error during the move operation, or on the second or subsequent call to the method. */ - public function moveTo($targetPath) + public function moveTo(string $targetPath): void { - if (!is_string($targetPath) || empty($targetPath)) { + if (empty($targetPath)) { throw new \InvalidArgumentException('Invalid path while moving an uploaded file.', 1436717307); } @@ -222,7 +187,7 @@ class UploadedFile implements UploadedFileInterface * * @return int|null The file size in bytes or null if unknown. */ - public function getSize() + public function getSize(): ?int { return $this->size; } @@ -240,7 +205,7 @@ class UploadedFile implements UploadedFileInterface * @see https://php.net/manual/en/features.file-upload.errors.php * @return int One of PHP's UPLOAD_ERR_XXX constants. */ - public function getError() + public function getError(): int { return $this->error; } @@ -256,7 +221,7 @@ class UploadedFile implements UploadedFileInterface * * @return string|null The filename sent by the client or null if none was provided. */ - public function getClientFilename() + public function getClientFilename(): ?string { return $this->clientFilename; } @@ -286,7 +251,7 @@ class UploadedFile implements UploadedFileInterface * * @return string|null The media type sent by the client or null if none was provided. */ - public function getClientMediaType() + public function getClientMediaType(): ?string { return $this->clientMediaType; } diff --git a/typo3/sysext/core/Classes/Http/Uri.php b/typo3/sysext/core/Classes/Http/Uri.php index 6cca65dd21d70defc1402519fc3898e863ff6a84..ffda18cf3f9599e51a66ce270dc2b681e2fe1115 100644 --- a/typo3/sysext/core/Classes/Http/Uri.php +++ b/typo3/sysext/core/Classes/Http/Uri.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /* * This file is part of the TYPO3 CMS project. * @@ -16,7 +18,6 @@ namespace TYPO3\CMS\Core\Http; use Psr\Http\Message\UriInterface; -use TYPO3\CMS\Core\Utility\MathUtility; /** * Represents a URI based on the PSR-7 Standard. @@ -43,81 +44,68 @@ class Uri implements UriInterface /** * The default scheme for the URI - * @var string */ - protected $scheme = ''; + protected string $scheme = ''; /** * @var int[] Associative array containing schemes and their default ports. */ - protected $supportedSchemes = [ + protected array $supportedSchemes = [ 'http' => 80, 'https' => 443, ]; /** * The authority part of the URI - * @var string */ - protected $authority = ''; + protected string $authority = ''; /** * The userInfo part of the URI - * @var string */ - protected $userInfo = ''; + protected string $userInfo = ''; /** * The host part of the URI - * @var string */ - protected $host = ''; + protected string $host = ''; /** * The port of the URI (empty if it is the standard port for the scheme) - * @var int|null */ - protected $port; + protected ?int $port = null; /** * The path part of the URI (can be empty or /) - * @var string */ - protected $path = ''; + protected string $path = ''; /** * The query part of the URI without the ? - * @var string */ - protected $query = ''; + protected string $query = ''; /** * The fragment part of the URI without the # before - * @var string */ - protected $fragment; + protected string $fragment = ''; /** - * @param string|null $uri The full URI including query string and fragment + * @param string $uri The full URI including query string and fragment * @throws \InvalidArgumentException when the URI is not a string */ - public function __construct($uri = '') + public function __construct(string $uri = '') { - if (!is_string($uri)) { - $argumentType = get_debug_type($uri); - throw new \InvalidArgumentException('URI passed must be a string, but is of type "' . $argumentType . '"', 1436717320); - } if (!empty($uri)) { $this->parseUri($uri); } } /** - * helper function for parsing the full URI string - * @param string $uri + * Helper to parse the full URI string * @throws \InvalidArgumentException if the URI is malformed. */ - protected function parseUri($uri) + protected function parseUri(string $uri): void { $uriParts = parse_url($uri); @@ -128,30 +116,24 @@ class Uri implements UriInterface if (isset($uriParts['scheme'])) { $this->scheme = $this->sanitizeScheme($uriParts['scheme']); } - if (isset($uriParts['user'])) { $this->userInfo = $uriParts['user']; if (isset($uriParts['pass'])) { $this->userInfo .= ':' . $uriParts['pass']; } } - if (isset($uriParts['host'])) { $this->host = $uriParts['host']; } - if (isset($uriParts['port'])) { $this->port = (int)$uriParts['port']; } - if (isset($uriParts['path'])) { $this->path = $this->sanitizePath($uriParts['path']); } - if (isset($uriParts['query'])) { $this->query = $this->sanitizeQuery($uriParts['query']); } - if (isset($uriParts['fragment'])) { $this->fragment = $this->sanitizeFragment($uriParts['fragment']); } @@ -171,7 +153,7 @@ class Uri implements UriInterface * @see https://tools.ietf.org/html/rfc3986#section-3.1 * @return string The URI scheme. */ - public function getScheme() + public function getScheme(): string { return $this->scheme; } @@ -194,7 +176,7 @@ class Uri implements UriInterface * @see https://tools.ietf.org/html/rfc3986#section-3.2 * @return string The URI authority, in "[user-info@]host[:port]" format. */ - public function getAuthority() + public function getAuthority(): string { if (empty($this->host)) { return ''; @@ -227,7 +209,7 @@ class Uri implements UriInterface * * @return string The URI user information, in "username[:password]" format. */ - public function getUserInfo() + public function getUserInfo(): string { return $this->userInfo; } @@ -243,7 +225,7 @@ class Uri implements UriInterface * @see https://tools.ietf.org/html/rfc3986#section-3.2.2 * @return string The URI host. */ - public function getHost() + public function getHost(): string { return $this->host; } @@ -263,7 +245,7 @@ class Uri implements UriInterface * * @return int|null The URI port. */ - public function getPort() + public function getPort(): ?int { return $this->isNonStandardPort($this->scheme, $this->host, $this->port) ? $this->port : null; } @@ -293,7 +275,7 @@ class Uri implements UriInterface * @see https://tools.ietf.org/html/rfc3986#section-3.3 * @return string The URI path. */ - public function getPath() + public function getPath(): string { return $this->path; } @@ -318,7 +300,7 @@ class Uri implements UriInterface * @see https://tools.ietf.org/html/rfc3986#section-3.4 * @return string The URI query string. */ - public function getQuery() + public function getQuery(): string { return $this->query; } @@ -339,7 +321,7 @@ class Uri implements UriInterface * @see https://tools.ietf.org/html/rfc3986#section-3.5 * @return string The URI fragment. */ - public function getFragment() + public function getFragment(): string { return $this->fragment; } @@ -356,14 +338,12 @@ class Uri implements UriInterface * An empty scheme is equivalent to removing the scheme. * * @param string $scheme The scheme to use with the new instance. - * * @return static A new instance with the specified scheme. * @throws \InvalidArgumentException for invalid or unsupported schemes. */ - public function withScheme($scheme) + public function withScheme(string $scheme): UriInterface { $scheme = $this->sanitizeScheme($scheme); - $clonedObject = clone $this; $clonedObject->scheme = $scheme; return $clonedObject; @@ -379,12 +359,12 @@ class Uri implements UriInterface * user; an empty string for the user is equivalent to removing user * information. * - * @param string $user The user name to use for authority. + * @param string $user The username to use for authority. * @param string|null $password The password associated with $user. * * @return static A new instance with the specified user information. */ - public function withUserInfo($user, $password = null) + public function withUserInfo(string $user, ?string $password = null): UriInterface { $userInfo = $user; if (!empty($password)) { @@ -405,11 +385,10 @@ class Uri implements UriInterface * An empty host value is equivalent to removing the host. * * @param string $host The hostname to use with the new instance. - * * @return static A new instance with the specified host. * @throws \InvalidArgumentException for invalid hostnames. */ - public function withHost($host) + public function withHost(string $host): UriInterface { $clonedObject = clone $this; $clonedObject->host = $host; @@ -430,19 +409,12 @@ class Uri implements UriInterface * * @param int|null $port The port to use with the new instance; a null value * removes the port information. - * * @return static A new instance with the specified port. * @throws \InvalidArgumentException for invalid ports. */ - public function withPort($port) + public function withPort(?int $port): UriInterface { if ($port !== null) { - if (MathUtility::canBeInterpretedAsInteger($port) === false) { - $argumentType = get_debug_type($port); - throw new \InvalidArgumentException('Invalid port "' . $argumentType . '" specified, must be an integer.', 1436717324); - } - - $port = (int)$port; if ($port < 1 || $port > 65535) { throw new \InvalidArgumentException('Invalid port "' . $port . '" specified, must be a valid TCP/UDP port.', 1436717326); } @@ -472,16 +444,11 @@ class Uri implements UriInterface * Implementations ensure the correct encoding as outlined in getPath(). * * @param string $path The path to use with the new instance. - * * @return static A new instance with the specified path. * @throws \InvalidArgumentException for invalid paths. */ - public function withPath($path) + public function withPath(string $path): UriInterface { - if (!is_string($path)) { - throw new \InvalidArgumentException('Invalid path provided. Must be of type string.', 1436717328); - } - if (str_contains($path, '?')) { throw new \InvalidArgumentException('Invalid path provided. Must not contain a query string.', 1436717330); } @@ -508,16 +475,11 @@ class Uri implements UriInterface * An empty query string value is equivalent to removing the query string. * * @param string $query The query string to use with the new instance. - * * @return static A new instance with the specified query string. * @throws \InvalidArgumentException for invalid query strings. */ - public function withQuery($query) + public function withQuery(string $query): UriInterface { - if (!is_string($query)) { - throw new \InvalidArgumentException('Query string must be a string.', 1436717334); - } - if (str_contains($query, '#')) { throw new \InvalidArgumentException('Query string must not include a URI fragment.', 1436717336); } @@ -540,10 +502,9 @@ class Uri implements UriInterface * An empty fragment value is equivalent to removing the fragment. * * @param string $fragment The fragment to use with the new instance. - * * @return static A new instance with the specified fragment. */ - public function withFragment($fragment) + public function withFragment(string $fragment): UriInterface { $fragment = $this->sanitizeFragment($fragment); $clonedObject = clone $this; @@ -572,9 +533,8 @@ class Uri implements UriInterface * - If a fragment is present, it MUST be prefixed by "#". * * @see https://tools.ietf.org/html/rfc3986#section-4.1 - * @return string */ - public function __toString() + public function __toString(): string { $uri = ''; @@ -604,22 +564,15 @@ class Uri implements UriInterface /** * Is a given port non-standard for the current scheme? - * - * @param string $scheme - * @param string $host - * @param int|null $port - * @return bool */ - protected function isNonStandardPort($scheme, $host, $port) + protected function isNonStandardPort(string $scheme, string $host, ?int $port): bool { if (empty($scheme)) { return empty($host) || !empty($port); } - if (empty($host) || empty($port)) { return false; } - return !isset($this->supportedSchemes[$scheme]) || $port !== $this->supportedSchemes[$scheme]; } @@ -627,11 +580,10 @@ class Uri implements UriInterface * Filters the scheme to ensure it is a valid scheme. * * @param string $scheme Scheme name. - * * @return string Filtered scheme. * @throws \InvalidArgumentException when a scheme is given which is not supported */ - protected function sanitizeScheme($scheme) + protected function sanitizeScheme(string $scheme): string { $scheme = strtolower($scheme); $scheme = preg_replace('#:(//)?$#', '', $scheme); @@ -649,11 +601,8 @@ class Uri implements UriInterface /** * Filters the path of a URI to ensure it is properly encoded. - * - * @param string $path - * @return string */ - protected function sanitizePath($path) + protected function sanitizePath(string $path): string { return preg_replace_callback( '/(?:[^' . self::UNRESERVED_CHARLIST . ':@&=\+\$,\/;%]+|%(?![A-Fa-f0-9]{2}))/', @@ -666,13 +615,9 @@ class Uri implements UriInterface /** * Filter a query string to ensure it is properly encoded. - * * Ensures that the values in the query string are properly urlencoded. - * - * @param string $query - * @return string */ - protected function sanitizeQuery($query) + protected function sanitizeQuery(string $query): string { if (!empty($query) && str_starts_with($query, '?')) { $query = substr($query, 1); @@ -694,10 +639,9 @@ class Uri implements UriInterface /** * Split a query value into a key/value tuple. * - * @param string $value * @return array A value with exactly two elements, key and value */ - protected function splitQueryValue($value) + protected function splitQueryValue(string $value): array { $data = explode('=', $value, 2); if (count($data) === 1) { @@ -708,30 +652,19 @@ class Uri implements UriInterface /** * Filter a fragment value to ensure it is properly encoded. - * - * @param string|null $fragment - * @return string */ - protected function sanitizeFragment($fragment) + protected function sanitizeFragment(string $fragment): string { - if ($fragment === null) { - $fragment = ''; - } - if (!empty($fragment) && str_starts_with($fragment, '#')) { $fragment = substr($fragment, 1); } - return $this->sanitizeQueryOrFragment($fragment); } /** * Filter a query string key or value, or a fragment. - * - * @param string $value - * @return string */ - protected function sanitizeQueryOrFragment($value) + protected function sanitizeQueryOrFragment(string $value): string { return preg_replace_callback( '/(?:[^' . self::UNRESERVED_CHARLIST . self::SUBDELIMITER_CHARLIST . '%:@\/\?]+|%(?![A-Fa-f0-9]{2}))/', diff --git a/typo3/sysext/core/Classes/Security/ContentSecurityPolicy/UriValue.php b/typo3/sysext/core/Classes/Security/ContentSecurityPolicy/UriValue.php index bdbd5ccd164d6a444824e9b17f7622ee9d92004d..3dd292a00428a91bc47a0fcb9ada9a72294c4246 100644 --- a/typo3/sysext/core/Classes/Security/ContentSecurityPolicy/UriValue.php +++ b/typo3/sysext/core/Classes/Security/ContentSecurityPolicy/UriValue.php @@ -85,7 +85,7 @@ final class UriValue extends Uri implements \Stringable, EqualityInterface, Cove return $this->domainName; } - protected function parseUri($uri): void + protected function parseUri(string $uri): void { parent::parseUri($uri); // ignore fragments per default diff --git a/typo3/sysext/core/Tests/Unit/Http/RequestTest.php b/typo3/sysext/core/Tests/Unit/Http/RequestTest.php index 15cf1063236adc71f2bd89a9b64df4b0b4b09e1f..81b2b5b695d5e13c063be9b4f39441b434e70e62 100644 --- a/typo3/sysext/core/Tests/Unit/Http/RequestTest.php +++ b/typo3/sysext/core/Tests/Unit/Http/RequestTest.php @@ -55,14 +55,6 @@ final class RequestTest extends UnitTestCase self::assertEquals('GET', $request->getMethod()); } - /** - * @test - */ - public function getUriIsNullByDefault(): void - { - self::assertNull($this->request->getUri()); - } - /** * @test */ diff --git a/typo3/sysext/core/Tests/Unit/Http/ResponseTest.php b/typo3/sysext/core/Tests/Unit/Http/ResponseTest.php index 5d4bf9ae8135950ed5d73aa23b85780a3cf5a571..0a2f6b4d2b09579948446f988aeae152e58ae0c1 100644 --- a/typo3/sysext/core/Tests/Unit/Http/ResponseTest.php +++ b/typo3/sysext/core/Tests/Unit/Http/ResponseTest.php @@ -21,11 +21,6 @@ use TYPO3\CMS\Core\Http\Response; use TYPO3\CMS\Core\Http\Stream; use TYPO3\TestingFramework\Core\Unit\UnitTestCase; -/** - * Testcase for \TYPO3\CMS\Core\Http\Response - * - * Adapted from https://github.com/phly/http/ - */ final class ResponseTest extends UnitTestCase { protected ?Response $response; @@ -59,11 +54,6 @@ final class ResponseTest extends UnitTestCase return [ 'too-low' => [99], 'too-high' => [600], - 'null' => [null], - 'bool' => [true], - 'string' => ['foo'], - 'array' => [[200]], - 'object' => [(object)[200]], ]; } @@ -124,12 +114,6 @@ final class ResponseTest extends UnitTestCase public static function invalidStatusDataProvider(): array { return [ - 'true' => [true], - 'false' => [false], - 'float' => [100.1], - 'bad-string' => ['Two hundred'], - 'array' => [[200]], - 'object' => [(object)['statusCode' => 200]], 'too-small' => [1], 'too-big' => [600], ]; diff --git a/typo3/sysext/core/Tests/Unit/Http/UploadedFileTest.php b/typo3/sysext/core/Tests/Unit/Http/UploadedFileTest.php index cce95194b5ed36a58f3f56880969b3bd9e9fabac..c24c399381bc763b99f8ba477c025deba3f69267 100644 --- a/typo3/sysext/core/Tests/Unit/Http/UploadedFileTest.php +++ b/typo3/sysext/core/Tests/Unit/Http/UploadedFileTest.php @@ -22,11 +22,6 @@ use TYPO3\CMS\Core\Http\UploadedFile; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\TestingFramework\Core\Unit\UnitTestCase; -/** - * Testcase for \TYPO3\CMS\Core\Http\UploadedFile - * - * Adapted from https://github.com/phly/http/ - */ final class UploadedFileTest extends UnitTestCase { protected $tmpFile; @@ -48,9 +43,6 @@ final class UploadedFileTest extends UnitTestCase public static function invalidStreamsDataProvider(): array { return [ - 'null' => [null], - 'true' => [true], - 'false' => [false], 'int' => [1], 'float' => [1.1], /* Have not figured out a valid way to test an invalid path yet; null byte injection @@ -72,40 +64,9 @@ final class UploadedFileTest extends UnitTestCase new UploadedFile($streamOrFile, 0, UPLOAD_ERR_OK); } - public static function invalidSizesDataProvider(): array - { - return [ - 'null' => [null], - 'true' => [true], - 'false' => [false], - 'float' => [1.1], - 'string' => ['1'], - 'array' => [[1]], - 'object' => [(object)[1]], - ]; - } - - /** - * @dataProvider invalidSizesDataProvider - * @test - */ - public function constructorRaisesExceptionOnInvalidSize($size): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionCode(1436717302); - new UploadedFile(fopen('php://temp', 'wb+'), $size, UPLOAD_ERR_OK); - } - public static function invalidErrorStatusesDataProvider(): array { return [ - 'null' => [null], - 'true' => [true], - 'false' => [false], - 'float' => [1.1], - 'string' => ['1'], - 'array' => [[1]], - 'object' => [(object)[1]], 'negative' => [-1], 'too-big' => [9], ]; @@ -122,40 +83,6 @@ final class UploadedFileTest extends UnitTestCase new UploadedFile(fopen('php://temp', 'wb+'), 0, $status); } - public static function invalidFilenamesAndMediaTypesDataProvider(): array - { - return [ - 'true' => [true], - 'false' => [false], - 'int' => [1], - 'float' => [1.1], - 'array' => [['string']], - 'object' => [(object)['string']], - ]; - } - - /** - * @dataProvider invalidFilenamesAndMediaTypesDataProvider - * @test - */ - public function constructorRaisesExceptionOnInvalidClientFilename($filename): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionCode(1436717304); - new UploadedFile(fopen('php://temp', 'wb+'), 0, UPLOAD_ERR_OK, $filename); - } - - /** - * @dataProvider invalidFilenamesAndMediaTypesDataProvider - * @test - */ - public function constructorRaisesExceptionOnInvalidClientMediaType($mediaType): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionCode(1436717305); - new UploadedFile(fopen('php://temp', 'wb+'), 0, UPLOAD_ERR_OK, 'foobar.baz', $mediaType); - } - /** * @test */ @@ -205,34 +132,17 @@ final class UploadedFileTest extends UnitTestCase self::assertEquals($stream->__toString(), $contents); } - public static function invalidMovePathsDataProvider(): array - { - return [ - 'null' => [null], - 'true' => [true], - 'false' => [false], - 'int' => [1], - 'float' => [1.1], - 'empty' => [''], - 'array' => [['filename']], - 'object' => [(object)['filename']], - ]; - } - /** - * @dataProvider invalidMovePathsDataProvider * @test */ - public function moveToRaisesExceptionForInvalidPath($path): void + public function moveToRaisesExceptionForEmptyPath(): void { $stream = new Stream('php://temp', 'wb+'); $stream->write('Foo bar!'); $upload = new UploadedFile($stream, 0, UPLOAD_ERR_OK); - - $this->tmpFile = $path; $this->expectException(\InvalidArgumentException::class); $this->expectExceptionCode(1436717307); - $upload->moveTo($path); + $upload->moveTo(''); } /** diff --git a/typo3/sysext/core/Tests/Unit/Http/UriTest.php b/typo3/sysext/core/Tests/Unit/Http/UriTest.php index 6d9b526a599afeb80547e15c9a58d96dd78440f4..24706bc63d77e2145bb50a900f7f7356d083c787 100644 --- a/typo3/sysext/core/Tests/Unit/Http/UriTest.php +++ b/typo3/sysext/core/Tests/Unit/Http/UriTest.php @@ -20,11 +20,6 @@ namespace TYPO3\CMS\Core\Tests\Unit\Http; use TYPO3\CMS\Core\Http\Uri; use TYPO3\TestingFramework\Core\Unit\UnitTestCase; -/** - * Testcase for \TYPO3\CMS\Core\Http\Uri - * - * Adapted from https://github.com/phly/http/ - */ final class UriTest extends UnitTestCase { /** @@ -123,8 +118,9 @@ final class UriTest extends UnitTestCase public static function validPortsDataProvider(): array { return [ - 'int' => [3000], - 'string' => ['3000'], + 'int 1' => [1], + 'int 3000' => [3000], + 'int 65535' => [65535], ]; } @@ -144,28 +140,6 @@ final class UriTest extends UnitTestCase ); } - public static function invalidPortsDataProviderType(): array - { - return [ - 'false' => [false], - 'string' => ['string'], - 'array' => [[3000]], - 'object' => [(object)[3000]], - ]; - } - - /** - * @dataProvider invalidPortsDataProviderType - * @test - */ - public function withPortRaisesExceptionForInvalidPortsByType($port): void - { - $uri = new Uri('https://user:pass@local.example.com:3001/foo?bar=baz#quz'); - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionCode(1436717324); - $uri->withPort($port); - } - public static function invalidPortsDataProviderRange(): array { return [ @@ -175,21 +149,6 @@ final class UriTest extends UnitTestCase ]; } - /** - * @test - * @todo: Currently, boolean true is interpreted as 1 by canBeInterpretedAsInteger(). - * @todo: This test shows that, but there is an inconsistency and maybe it would be better - * @todo: if the code would not accept 'true' as valid port but throw an exception instead. - * @todo: If that is changed, 'true' should be added to the 'invalid type' data provider above. - */ - public function withPortAcceptsBooleanTrueAsPortOne(): void - { - $uri = new Uri('https://user:pass@local.example.com:3001/foo?bar=baz#quz'); - $new = $uri->withPort(true); - self::assertNotSame($uri, $new); - self::assertEquals(1, $new->getPort()); - } - /** * @dataProvider invalidPortsDataProviderRange * @test @@ -241,29 +200,6 @@ final class UriTest extends UnitTestCase self::assertEquals('https://user:pass@local.example.com:3001/bar/baz?bar=baz#quz', (string)$new); } - public static function invalidPathsDataProvider(): array - { - return [ - 'null' => [null], - 'true' => [true], - 'false' => [false], - 'array' => [['/bar/baz']], - 'object' => [(object)['/bar/baz']], - ]; - } - - /** - * @dataProvider invalidPathsDataProvider - * @test - */ - public function withPathRaisesExceptionForInvalidPaths($path): void - { - $uri = new Uri('https://user:pass@local.example.com:3001/foo?bar=baz#quz'); - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionCode(1436717328); - $uri->withPath($path); - } - /** * @test */ @@ -298,29 +234,6 @@ final class UriTest extends UnitTestCase self::assertEquals('https://user:pass@local.example.com:3001/foo?baz=bat#quz', (string)$new); } - public static function invalidQueryStringsDataProvider(): array - { - return [ - 'null' => [null], - 'true' => [true], - 'false' => [false], - 'array' => [['baz=bat']], - 'object' => [(object)['baz=bat']], - ]; - } - - /** - * @dataProvider invalidQueryStringsDataProvider - * @test - */ - public function withQueryRaisesExceptionForInvalidQueryStringsByType($query): void - { - $uri = new Uri('https://user:pass@local.example.com:3001/foo?bar=baz#quz'); - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionCode(1436717334); - $uri->withQuery($query); - } - /** * @test */ diff --git a/typo3/sysext/core/composer.json b/typo3/sysext/core/composer.json index 0cc33027ed795bab0af9749c58cab3d1611a04b3..ceb4d6a34f343b38c2476b9dd9138c3f2790aeaa 100644 --- a/typo3/sysext/core/composer.json +++ b/typo3/sysext/core/composer.json @@ -41,14 +41,14 @@ "enshrined/svg-sanitize": "^0.15.4", "firebase/php-jwt": "^6.3.1", "guzzlehttp/guzzle": "^7.5.0", - "guzzlehttp/psr7": "^2.4.3", + "guzzlehttp/psr7": "^2.5.0", "lolli42/finediff": "^1.0.2", "masterminds/html5": "^2.7.6", "psr/container": "^2.0", "psr/event-dispatcher": "^1.0", "psr/http-client": "^1.0", "psr/http-factory": "^1.0", - "psr/http-message": "^1.0", + "psr/http-message": "^1.1 || ^2.0", "psr/http-server-handler": "^1.0", "psr/http-server-middleware": "^1.0", "psr/log": "^2.0 || ^3.0", diff --git a/typo3/sysext/extbase/Classes/Http/ForwardResponse.php b/typo3/sysext/extbase/Classes/Http/ForwardResponse.php index ef4d298460d1e1949bac1a2bcabcf2fd6e1c8358..5ca44f97b439db30d8e37842a3cf7bd8460f3487 100644 --- a/typo3/sysext/extbase/Classes/Http/ForwardResponse.php +++ b/typo3/sysext/extbase/Classes/Http/ForwardResponse.php @@ -22,15 +22,13 @@ use TYPO3\CMS\Extbase\Error\Result; class ForwardResponse extends Response { - private string $actionName; private ?string $controllerName = null; private ?string $extensionName = null; private ?array $arguments = null; private Result $argumentsValidationResult; - public function __construct(string $actionName) + public function __construct(private readonly string $actionName) { - $this->actionName = $actionName; $this->argumentsValidationResult = new Result(); parent::__construct('php://temp', 204); } diff --git a/typo3/sysext/form/composer.json b/typo3/sysext/form/composer.json index 6a1d1334e59d9f0a694f0d1403be51e765fe17aa..326704435a4d2a8f3fbe7ea52ab1c939f766d430 100644 --- a/typo3/sysext/form/composer.json +++ b/typo3/sysext/form/composer.json @@ -19,7 +19,7 @@ "sort-packages": true }, "require": { - "psr/http-message": "^1.0", + "psr/http-message": "^1.1 || ^2.0", "symfony/expression-language": "^6.2", "typo3/cms-core": "12.4.*@dev" }, diff --git a/typo3/sysext/redirects/composer.json b/typo3/sysext/redirects/composer.json index 5220e6fd8013e5e8181d29cd7279bfbe2d6081a9..d7b22dea2ad01b0a055319aac5d556e9691b0577 100644 --- a/typo3/sysext/redirects/composer.json +++ b/typo3/sysext/redirects/composer.json @@ -20,7 +20,7 @@ }, "require": { "doctrine/dbal": "^3.6.2", - "psr/http-message": "^1.0", + "psr/http-message": "^1.1 || ^2.0", "psr/log": "^2.0 || ^3.0", "symfony/console": "^6.2", "typo3/cms-backend": "12.4.*@dev",