Description
Symfony version(s) affected
6.3.6
Description
This issue rose while using the MapRequestPayload
Attribute on a request.
Consider the following DTO and Controller:
final class ChangePassword
{
#[SerializedName(serializedName: 'old_password')]
private ?string $oldPassword = null;
public function __construct(
#[Assert\NotNull,
Assert\NotBlank,
Assert\Email]
private string $email,
#[Assert\NotNull,
Assert\NotBlank]
private string $password,
?string $oldPassword = null
) {
$this->oldPassword = $oldPassword;
}
public function getEmail(): string
{
return $this->email;
}
public function getPassword(): string
{
return $this->password;
}
public function getOldPassword(): ?string
{
return $this->oldPassword;
}
}
#[Route(path: 'api/change-password', name: 'change-password', methods: ['POST'])]
public function changePasswordAction(#[MapRequestPayload] ChangePassword $changePassword): JsonResponse
{
return new JsonResponse($changePassword->getEmail());
}
When calling this route with
{
"password": "abc",
"old_password": "def"
}
the created object looks like this:
object(App\DTO\ChangePassword)#2315 (3) {
["oldPassword":"App\DTO\ChangePassword":private]=>
NULL
["email":"App\DTO\ChangePassword":private]=>
string(3) "abc"
["password":"App\DTO\ChangePassword":private]=>
string(3) "def"
}
the values are not correctly mapped
How to reproduce
A simple way to reproduce it is described above.
It's also possible to use my github project: https://github.com/Havrin/symfony-payload-bug
start it and throw the following request against https://localhost/api/change-password
{
"password": "abc",
"old_password": "def"
}
Possible Solution
While debugging I noticed, that https://github.com/symfony/serializer/blob/1197823bacefc3397fafb8f10709c1574b2f69ce/Normalizer/AbstractNormalizer.php#L376 is creating an array of values with just an index-number as key.
After creating the object in https://github.com/symfony/serializer/blob/1197823bacefc3397fafb8f10709c1574b2f69ce/Normalizer/AbstractNormalizer.php#L420 the values are wrongly mapped. Seems like the code is not correctly using the name as key but rather the index-number.
Additional Context
The wrong mapping started occurring after this fix: #51907