Skip to content

Commit

Permalink
bug #17140 [Serializer] Remove normalizer cache in Serializer class (…
Browse files Browse the repository at this point in the history
…jvasseur)

This PR was merged into the 2.3 branch.

Discussion
----------

[Serializer] Remove normalizer cache in Serializer class

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT
| Doc PR        |

The serializer cache the normalizer/denormalizer to use based only on the class and format. But the supportsNormalization and supportDenormalization methods can decide based on the data passed leading to hard to find bugs when the serializer used a cached normalizer it shouldn't use.

Commits
-------

8566dc1 Remove normalizer cache in Serializer class
  • Loading branch information
Tobion committed Jan 12, 2016
2 parents f1cce4e + 8566dc1 commit 85d5ed2
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 2 deletions.
2 changes: 0 additions & 2 deletions src/Symfony/Component/Serializer/Serializer.php
Expand Up @@ -237,7 +237,6 @@ private function normalizeObject($object, $format = null, array $context = array
foreach ($this->normalizers as $normalizer) {
if ($normalizer instanceof NormalizerInterface
&& $normalizer->supportsNormalization($object, $format)) {
$this->normalizerCache[$class][$format] = $normalizer;

return $normalizer->normalize($object, $format, $context);
}
Expand Down Expand Up @@ -272,7 +271,6 @@ private function denormalizeObject($data, $class, $format = null, array $context
foreach ($this->normalizers as $normalizer) {
if ($normalizer instanceof DenormalizerInterface
&& $normalizer->supportsDenormalization($data, $class, $format)) {
$this->denormalizerCache[$class][$format] = $normalizer;

return $normalizer->denormalize($data, $class, $format, $context);
}
Expand Down
44 changes: 44 additions & 0 deletions src/Symfony/Component/Serializer/Tests/SerializerTest.php
Expand Up @@ -73,6 +73,50 @@ public function testDenormalizeOnNormalizer()
$this->assertTrue($this->serializer->denormalize(json_encode($data), 'stdClass', 'json'));
}

public function testNormalizeWithSupportOnData()
{
$normalizer1 = $this->getMock('Symfony\Component\Serializer\Normalizer\NormalizerInterface');
$normalizer1->method('supportsNormalization')
->willReturnCallback(function ($data, $format) {
return isset($data->test);
});
$normalizer1->method('normalize')->willReturn('test1');

$normalizer2 = $this->getMock('Symfony\Component\Serializer\Normalizer\NormalizerInterface');
$normalizer2->method('supportsNormalization')
->willReturn(true);
$normalizer2->method('normalize')->willReturn('test2');

$serializer = new Serializer(array($normalizer1, $normalizer2));

$data = new \stdClass();
$data->test = true;
$this->assertEquals('test1', $serializer->normalize($data));

$this->assertEquals('test2', $serializer->normalize(new \stdClass()));
}

public function testDenormalizeWithSupportOnData()
{
$denormalizer1 = $this->getMock('Symfony\Component\Serializer\Normalizer\DenormalizerInterface');
$denormalizer1->method('supportsDenormalization')
->willReturnCallback(function ($data, $type, $format) {
return isset($data['test1']);
});
$denormalizer1->method('denormalize')->willReturn('test1');

$denormalizer2 = $this->getMock('Symfony\Component\Serializer\Normalizer\DenormalizerInterface');
$denormalizer2->method('supportsDenormalization')
->willReturn(true);
$denormalizer2->method('denormalize')->willReturn('test2');

$serializer = new Serializer(array($denormalizer1, $denormalizer2));

$this->assertEquals('test1', $serializer->denormalize(array('test1' => true), 'test'));

$this->assertEquals('test2', $serializer->denormalize(array(), 'test'));
}

public function testSerialize()
{
$this->serializer = new Serializer(array(new GetSetMethodNormalizer()), array('json' => new JsonEncoder()));
Expand Down

0 comments on commit 85d5ed2

Please sign in to comment.