Skip to content

Commit b6551e5

Browse files
Merge branch '8.0' into 8.1
* 8.0: [DependencyInjection] Update Container PHPDoc behaviors count when a service does not exist [Validator] Review translations for Portuguese (pt_BR) [Messenger][Cache] Align Redis sentinel auth handling across components Revert "bug #63380 [Messenger] Use mutable datetime columns in Doctrine transport schema (nicolas-grekas)" [HttpKernel] Handle invalid backed-enum values gracefully in RequestPayloadValueResolver fail gracefully when the semaphore config is used but the component is missing [Messenger] Use mutable datetime columns in Doctrine transport schema [DependencyInjection] Prevent false unused-env errors for abstract definitions removed at compile time [TypeInfo] Fix template key-type for array
2 parents 304bd39 + da9f06f commit b6551e5

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

Controller/ArgumentResolver/RequestPayloadValueResolver.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
use Symfony\Component\HttpKernel\Exception\NearMissValueResolverException;
2828
use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException;
2929
use Symfony\Component\HttpKernel\KernelEvents;
30+
use Symfony\Component\Serializer\Exception\InvalidArgumentException as SerializerInvalidArgumentException;
3031
use Symfony\Component\Serializer\Exception\NotEncodableValueException;
3132
use Symfony\Component\Serializer\Exception\PartialDenormalizationException;
3233
use Symfony\Component\Serializer\Exception\UnexpectedPropertyException;
@@ -146,6 +147,9 @@ public function onKernelControllerArguments(ControllerArgumentsEvent $event): vo
146147
$violations->add(new ConstraintViolation($message, $template, $parameters, null, $error->getPath(), null));
147148
}
148149
$payload = $e->getData();
150+
} catch (SerializerInvalidArgumentException $e) {
151+
$violations->add(new ConstraintViolation($e->getMessage(), $e->getMessage(), [], null, '', null));
152+
$payload = null;
149153
}
150154

151155
if (null !== $payload && !\count($violations)) {
@@ -165,6 +169,8 @@ public function onKernelControllerArguments(ControllerArgumentsEvent $event): vo
165169
$payload = $payloadMapper($request, $argument->metadata, $argument);
166170
} catch (PartialDenormalizationException $e) {
167171
throw HttpException::fromStatusCode($validationFailedCode, implode("\n", array_map(static fn ($e) => $e->getMessage(), $e->getErrors())), $e);
172+
} catch (SerializerInvalidArgumentException $e) {
173+
throw HttpException::fromStatusCode($validationFailedCode, $e->getMessage(), $e);
168174
}
169175
}
170176

Tests/Controller/ArgumentResolver/RequestPayloadValueResolverTest.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
3636
use Symfony\Component\Serializer\Exception\PartialDenormalizationException;
3737
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
38+
use Symfony\Component\Serializer\Normalizer\BackedEnumNormalizer;
3839
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
3940
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
4041
use Symfony\Component\Serializer\Serializer;
@@ -291,6 +292,37 @@ public function testValidationNotPassed()
291292
}
292293
}
293294

295+
public function testValidationFailedOnInvalidBackedEnum()
296+
{
297+
$content = '{"method": "INVALID"}';
298+
$serializer = new Serializer([new BackedEnumNormalizer(), new ObjectNormalizer()], ['json' => new JsonEncoder()]);
299+
300+
$validator = $this->createMock(ValidatorInterface::class);
301+
$validator->expects($this->never())
302+
->method('validate');
303+
304+
$resolver = new RequestPayloadValueResolver($serializer, $validator);
305+
306+
$argument = new ArgumentMetadata('invalid', RequestPayloadWithBackedEnum::class, false, false, null, false, [
307+
MapRequestPayload::class => new MapRequestPayload(),
308+
]);
309+
$request = Request::create('/', 'POST', server: ['CONTENT_TYPE' => 'application/json'], content: $content);
310+
311+
$kernel = $this->createStub(HttpKernelInterface::class);
312+
$arguments = $resolver->resolve($request, $argument);
313+
$event = new ControllerArgumentsEvent($kernel, function () {}, $arguments, $request, HttpKernelInterface::MAIN_REQUEST);
314+
315+
try {
316+
$resolver->onKernelControllerArguments($event);
317+
$this->fail(\sprintf('Expected "%s" to be thrown.', HttpException::class));
318+
} catch (HttpException $e) {
319+
$validationFailedException = $e->getPrevious();
320+
$this->assertSame(422, $e->getStatusCode());
321+
$this->assertInstanceOf(ValidationFailedException::class, $validationFailedException);
322+
$this->assertSame('The data must belong to a backed enumeration of type Symfony\\Component\\HttpKernel\\Tests\\Controller\\ArgumentResolver\\RequestMethod', $validationFailedException->getViolations()[0]->getMessage());
323+
}
324+
}
325+
294326
public function testValidationNotPerformedWhenPartialDenormalizationReturnsViolation()
295327
{
296328
$content = '{"password": "abc"}';
@@ -1276,6 +1308,19 @@ public function getPassword(): string
12761308
}
12771309
}
12781310

1311+
class RequestPayloadWithBackedEnum
1312+
{
1313+
public function __construct(public readonly RequestMethod $method)
1314+
{
1315+
}
1316+
}
1317+
1318+
enum RequestMethod: string
1319+
{
1320+
case GET = 'GET';
1321+
case POST = 'POST';
1322+
}
1323+
12791324
class ObjectWithBoolArgument
12801325
{
12811326
public function __construct(public readonly ?bool $value = null)

0 commit comments

Comments
 (0)