Skip to content

Commit

Permalink
fix deserialization of incorrect types into enums
Browse files Browse the repository at this point in the history
  • Loading branch information
VasekPurchart committed Oct 20, 2021
2 parents 38815d1 + 6b70ed6 commit 079bbcc
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 2 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
],
"require": {
"php": "~7.2",
"consistence/consistence": "~1.0|~2.0",
"consistence/consistence": "^2.0.2",
"jms/serializer": "~2.0|~3.0"
},
"require-dev": {
Expand Down
11 changes: 10 additions & 1 deletion src/Enum/EnumSerializerHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ private function deserializeEnumValue(DeserializationVisitorInterface $visitor,
return $enumClass::getMultiByEnums($singleEnums);
}

if ($this->isMultiEnumClass($enumClass) && Type::getType($data) !== 'int') {
throw new \Consistence\Enum\InvalidEnumValueException($data, $enumClass);
}

return $enumClass::get($this->deserializationVisitType($visitor, $data, $type));
}

Expand Down Expand Up @@ -274,9 +278,14 @@ private function findParameter(array $type, Closure $callback): ?array
return ArrayType::findValueByCallback($type['params'], $callback);
}

private function isMultiEnumClass(string $enumClass): bool
{
return is_a($enumClass, MultiEnum::class, true);
}

private function checkMultiEnum(string $enumClass): void
{
if (!is_a($enumClass, MultiEnum::class, true)) {
if (!$this->isMultiEnumClass($enumClass)) {
throw new \Consistence\JmsSerializer\Enum\NotMultiEnumException($enumClass);
}
}
Expand Down
57 changes: 57 additions & 0 deletions tests/Enum/EnumSerializerHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,63 @@ public function testDeserializeEnumInvalidValueEmbededObject(): void
}
}

public function testDeserializeEnumWhenValueIsArray(): void
{
$serializer = $this->getSerializer();

try {
$serializer->deserialize('{
"single_enum": [1, 2, 3]
}', User::class, 'json');

$this->fail('Exception expected.');

} catch (\Consistence\JmsSerializer\Enum\DeserializationInvalidValueException $e) {
$this->assertEquals('single_enum', $e->getFieldPath());
$previous = $e->getPrevious();
$this->assertInstanceOf(\Consistence\Enum\InvalidEnumValueException::class, $previous);
$this->assertEquals([1, 2, 3], $previous->getValue());
}
}

public function testDeserializeEnumWhenValueIsObject(): void
{
$serializer = $this->getSerializer();

try {
$serializer->deserialize('{
"single_enum": {"foo": "bar"}
}', User::class, 'json');

$this->fail('Exception expected.');

} catch (\Consistence\JmsSerializer\Enum\DeserializationInvalidValueException $e) {
$this->assertEquals('single_enum', $e->getFieldPath());
$previous = $e->getPrevious();
$this->assertInstanceOf(\Consistence\Enum\InvalidEnumValueException::class, $previous);
$this->assertEquals(['foo' => 'bar'], $previous->getValue());
}
}

public function testDeserializeMultiEnumWithInvalidValueType(): void
{
$serializer = $this->getSerializer();

try {
$serializer->deserialize(sprintf('{
"multi_enum": "%s"
}', 'foo'), User::class, 'json');

$this->fail('Exception expected.');

} catch (\Consistence\JmsSerializer\Enum\DeserializationInvalidValueException $e) {
$this->assertEquals('multi_enum', $e->getFieldPath());
$previous = $e->getPrevious();
$this->assertInstanceOf(\Consistence\Enum\InvalidEnumValueException::class, $previous);
$this->assertSame('foo', $previous->getValue());
}
}

public function testSerializeEnumAsSingleEnumsArrayNotMappedSingleEnum(): void
{
$user = new User();
Expand Down

0 comments on commit 079bbcc

Please sign in to comment.