diff --git a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestPayloadValueResolver.php b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestPayloadValueResolver.php index c35d5e7e29381..59a1030ca807d 100644 --- a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestPayloadValueResolver.php +++ b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestPayloadValueResolver.php @@ -170,7 +170,14 @@ public function onKernelControllerArguments(ControllerArgumentsEvent $event): vo }; } - $arguments[$i] = $payload; + if ($argument->metadata->isVariadic()) { + if (!\is_array($payload) || !\array_is_list($payload)) { + throw HttpException::fromStatusCode($validationFailedCode); + } + \array_splice($arguments, $i, \count($payload), $payload); + } else { + $arguments[$i] = $payload; + } } $event->setArguments($arguments); @@ -233,6 +240,11 @@ private function mapRequestPayload(Request $request, ArgumentMetadata $argument, private function mapUploadedFile(Request $request, ArgumentMetadata $argument, MapUploadedFile $attribute): UploadedFile|array|null { - return $request->files->get($attribute->name ?? $argument->getName(), []); + $default = null; + if ($argument->isVariadic() || 'array' === $argument->getType()) { + $default = []; + } + + return $request->files->get($attribute->name ?? $argument->getName(), $default); } } diff --git a/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/UploadedFileValueResolverTest.php b/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/UploadedFileValueResolverTest.php index 5eb0d32483ed5..8817ee64ae6ae 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/UploadedFileValueResolverTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/UploadedFileValueResolverTest.php @@ -68,7 +68,7 @@ public function testEmpty(RequestPayloadValueResolver $resolver, Request $reques $attribute = new MapUploadedFile(); $argument = new ArgumentMetadata( 'qux', - UploadedFile::class, + 'array', false, false, null, @@ -82,12 +82,70 @@ static function () {}, $request, HttpKernelInterface::MAIN_REQUEST ); + $resolver->onKernelControllerArguments($event); $data = $event->getArguments()[0]; $this->assertEmpty($data); } + /** + * @dataProvider provideContext + */ + public function testNotNullableFile(RequestPayloadValueResolver $resolver, Request $request) + { + $attribute = new MapUploadedFile(); + $argument = new ArgumentMetadata( + 'qux', + UploadedFile::class, + false, + false, + null, + false, + [$attribute::class => $attribute] + ); + $event = new ControllerArgumentsEvent( + $this->createMock(HttpKernelInterface::class), + static function () {}, + $resolver->resolve($request, $argument), + $request, + HttpKernelInterface::MAIN_REQUEST + ); + + $this->expectException(HttpException::class); + + $resolver->onKernelControllerArguments($event); + } + + /** + * @dataProvider provideContext + */ + public function testNullableFile(RequestPayloadValueResolver $resolver, Request $request) + { + $attribute = new MapUploadedFile(); + $argument = new ArgumentMetadata( + 'qux', + UploadedFile::class, + false, + true, + null, + true, + [$attribute::class => $attribute] + ); + $event = new ControllerArgumentsEvent( + $this->createMock(HttpKernelInterface::class), + static function () {}, + $resolver->resolve($request, $argument), + $request, + HttpKernelInterface::MAIN_REQUEST + ); + + $resolver->onKernelControllerArguments($event); + $data = $event->getArguments()[0]; + + $this->assertNull($data); + } + /** * @dataProvider provideContext */ @@ -269,7 +327,7 @@ static function () {}, $resolver->onKernelControllerArguments($event); /** @var UploadedFile[] $data */ - $data = $event->getArguments()[0]; + $data = $event->getArguments(); $this->assertCount(2, $data); $this->assertSame('file-small.txt', $data[0]->getFilename());
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: