Skip to content

Commit

Permalink
bug #34791 [Serializer] Skip uninitialized (PHP 7.4) properties in Pr…
Browse files Browse the repository at this point in the history
…opertyNormalizer and ObjectNormalizer (vudaltsov)

This PR was squashed before being merged into the 3.4 branch (closes #34791).

Discussion
----------

[Serializer] Skip uninitialized (PHP 7.4) properties in PropertyNormalizer and ObjectNormalizer

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | n/a
| License       | MIT
| Doc PR        | n/a

When trying to read from an uninitialized property in PHP 7.4, a `TypeError` is generated, see https://wiki.php.net/rfc/typed_properties_v2#uninitialized_and_unset_properties. This PR fixes the issue.

Commits
-------

1ed8e42 [Serializer] Skip uninitialized (PHP 7.4) properties in PropertyNormalizer and ObjectNormalizer
  • Loading branch information
fabpot committed Dec 15, 2019
2 parents 00c775e + 1ed8e42 commit 8f42a76
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 0 deletions.
Expand Up @@ -83,8 +83,14 @@ protected function extractAttributes($object, $format = null, array $context = [
}
}

$checkPropertyInitialization = \PHP_VERSION_ID >= 70400;

// properties
foreach ($reflClass->getProperties(\ReflectionProperty::IS_PUBLIC) as $reflProperty) {
if ($checkPropertyInitialization && !$reflProperty->isInitialized($object)) {
continue;
}

if ($reflProperty->isStatic() || !$this->isAllowedAttribute($object, $reflProperty->name, $format, $context)) {
continue;
}
Expand Down
11 changes: 11 additions & 0 deletions src/Symfony/Component/Serializer/Normalizer/PropertyNormalizer.php
Expand Up @@ -99,9 +99,20 @@ protected function extractAttributes($object, $format = null, array $context = [
{
$reflectionObject = new \ReflectionObject($object);
$attributes = [];
$checkPropertyInitialization = \PHP_VERSION_ID >= 70400;

do {
foreach ($reflectionObject->getProperties() as $property) {
if ($checkPropertyInitialization) {
if (!$property->isPublic()) {
$property->setAccessible(true);
}

if (!$property->isInitialized($object)) {
continue;
}
}

if (!$this->isAllowedAttribute($reflectionObject->getName(), $property->name, $format, $context)) {
continue;
}
Expand Down
22 changes: 22 additions & 0 deletions src/Symfony/Component/Serializer/Tests/Fixtures/Php74Dummy.php
@@ -0,0 +1,22 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Serializer\Tests\Fixtures;

/**
* @author Valentin Udaltsov <udaltsov.valentin@gmail.com>
*/
final class Php74Dummy
{
public string $uninitializedProperty;

public string $initializedProperty = 'defaultValue';
}
Expand Up @@ -28,6 +28,7 @@
use Symfony\Component\Serializer\Tests\Fixtures\CircularReferenceDummy;
use Symfony\Component\Serializer\Tests\Fixtures\GroupDummy;
use Symfony\Component\Serializer\Tests\Fixtures\MaxDepthDummy;
use Symfony\Component\Serializer\Tests\Fixtures\Php74Dummy;
use Symfony\Component\Serializer\Tests\Fixtures\SiblingHolder;

/**
Expand Down Expand Up @@ -81,6 +82,18 @@ public function testNormalize()
);
}

/**
* @requires PHP 7.4
*/
public function testNormalizeObjectWithUninitializedProperties()
{
$obj = new Php74Dummy();
$this->assertEquals(
['initializedProperty' => 'defaultValue'],
$this->normalizer->normalize($obj, 'any')
);
}

public function testDenormalize()
{
$obj = $this->normalizer->denormalize(
Expand Down
Expand Up @@ -22,6 +22,7 @@
use Symfony\Component\Serializer\Tests\Fixtures\GroupDummy;
use Symfony\Component\Serializer\Tests\Fixtures\GroupDummyChild;
use Symfony\Component\Serializer\Tests\Fixtures\MaxDepthDummy;
use Symfony\Component\Serializer\Tests\Fixtures\Php74Dummy;
use Symfony\Component\Serializer\Tests\Fixtures\PropertyCircularReferenceDummy;
use Symfony\Component\Serializer\Tests\Fixtures\PropertySiblingHolder;

Expand Down Expand Up @@ -55,6 +56,18 @@ public function testNormalize()
);
}

/**
* @requires PHP 7.4
*/
public function testNormalizeObjectWithUninitializedProperties()
{
$obj = new Php74Dummy();
$this->assertEquals(
['initializedProperty' => 'defaultValue'],
$this->normalizer->normalize($obj, 'any')
);
}

public function testDenormalize()
{
$obj = $this->normalizer->denormalize(
Expand Down

0 comments on commit 8f42a76

Please sign in to comment.