Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[serializer] prevent mixup in normalizer of the object to populate #30977

Merged
merged 1 commit into from Apr 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -330,6 +330,8 @@ protected function instantiateObject(array &$data, $class, array &$context, \Ref

return $object;
}
// clean up even if no match
unset($context[static::OBJECT_TO_POPULATE]);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this means we keep silently ignoring a non-matching object_to_populate. should we instead throw an exception when object to populate is set in the options but does not match? it seems to me that it indicates a programmer error.

not sure about BC of throwing the exception though. its in some way a bugfix, but could break existing code when relying on the serializer silently ignoring the mistake.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not throw an exception in 3.4 for BC reason. We can keep the code as is in 3.4, generate a deprecation notice on master, and throw an exception in 5.0.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great plan! tell me when this is merged to master, then i do the deprecation pull request.


$constructor = $this->getConstructor($data, $class, $context, $reflectionClass, $allowedAttributes);
if ($constructor) {
Expand Down
Expand Up @@ -315,6 +315,30 @@ public function testGroupsDenormalizeWithNameConverter()
);
}

public function testObjectToPopulateNoMatch()
{
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$this->normalizer = new ObjectNormalizer($classMetadataFactory, null, null, new PhpDocExtractor());
new Serializer([$this->normalizer]);

$objectToPopulate = new ObjectInner();
$objectToPopulate->foo = 'foo';

$outer = $this->normalizer->denormalize([
'foo' => 'foo',
'inner' => [
'bar' => 'bar',
],
], ObjectOuter::class, null, [ObjectNormalizer::OBJECT_TO_POPULATE => $objectToPopulate]);

$this->assertInstanceOf(ObjectOuter::class, $outer);
$inner = $outer->getInner();
$this->assertInstanceOf(ObjectInner::class, $inner);
$this->assertNotSame($objectToPopulate, $inner);
$this->assertSame('bar', $inner->bar);
$this->assertNull($inner->foo);
}

/**
* @dataProvider provideCallbacks
*/
Expand Down Expand Up @@ -936,6 +960,9 @@ class ObjectOuter
{
public $foo;
public $bar;
/**
* @var ObjectInner
*/
private $inner;
private $date;

Expand Down