Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Serializer] ObjectNormalizer breaks when used with PropertyInfoExtractorInterface #54787

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

Closed
Steveb-p opened this issue Apr 30, 2024 · 5 comments

Comments

@Steveb-p
Copy link
Contributor

Steveb-p commented Apr 30, 2024

Symfony version(s) affected

5.4.39, 6.4.7, 7.0.7

Description

In the following commit, a change was introduced to the ObjectNormalizer constructor signature.
900d034

Now, ObjectNormalizer requires PropertyInfoExtractorInterface to be passed as last argument (or a null value).
This is aliased in framework to match property_info service.

->alias(PropertyInfoExtractorInterface::class, 'property_info')

So, under normal circumstances in an application that uses Symfony framework, this is filled with PropertyInfoExtractorInterface (when autowiring, for example).

If null value is passed, ReflectionExtractor object is created in it's stead.

$this->propertyInfoExtractor = $propertyInfoExtractor ?: new ReflectionExtractor();

However, ReflectionExtractor is not a representation of PropertyInfoExtractorInterface.

class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTypeExtractorInterface, PropertyAccessExtractorInterface, PropertyInitializableExtractorInterface, PropertyReadInfoExtractorInterface, PropertyWriteInfoExtractorInterface, ConstructorArgumentTypeExtractorInterface

On the following line:

return $this->propertyInfoExtractor->isWritable($class, $attribute)
|| ($writeInfo = $this->propertyInfoExtractor->getWriteInfo($class, $attribute)) && PropertyWriteInfo::TYPE_NONE !== $writeInfo->getType();

...the property that can contain either PropertyInfoExtractorInterface or ReflectionExtractor is used - a method getWriteInfo() is called that exists only on ReflectionExtractor. This means that PropertyInfoExtractorInterface cannot be used and will cause a PHP error, which results in inability to denormalize that object.

Ergo, in case of our app, we cannot use the property_info service (nor it's caching), and must fall back to null.

How to reproduce

We have this error...

Caused by
 Error: Call to undefined method Symfony\Component\PropertyInfo\PropertyInfoExtractor::getWriteInfo()

...happen when ObjectNormalizer is asked to denormalize an object of the following type:

$objectState = $this->denormalizer->denormalize($data, ObjectState::class, $format, $context);
final class ObjectState
{
    /** @var string */
    public $identifier;

    /** @var string */
    public $groupIdentifier;

    private function __construct(string $identifier, string $groupIdentifier)
    {
        $this->identifier = $identifier;
        $this->groupIdentifier = $groupIdentifier;
    }
}

with data (partial extract):

action: assign_object_state
identifier: locked
groupIdentifier: ez_lock

The ObjectNormalizer service is defined as follows:

    foo.serializer.object_normalizer:
        class: Symfony\Component\Serializer\Normalizer\ObjectNormalizer
        arguments:
            $propertyTypeExtractor: '@property_info'
            $propertyInfoExtractor: '@property_info'
        tags:
            - serializer.normalizer # a different tag is used in our own code since we have a dedicated serializer, but you get the idea.

Possible Solution

ObjectNormalizer, in lieu of adding PropertyInfoExtractorInterface to ReflectionExtractor, should perform checks against method presence to better inform developers about what is actually going on and/or a fallback should exist in cases where we are not dealing with ReflectionExtractor instance.

Additional Context

No response

@xabbuh
Copy link
Member

xabbuh commented May 2, 2024

see #54804

@Steveb-p
Copy link
Contributor Author

Steveb-p commented May 2, 2024

Thank you very much @xabbuh for looking into it 🙇

@fabpot fabpot closed this as completed in 963b29d May 2, 2024
@nexik
Copy link

nexik commented May 6, 2024

Will this be available in 7.0.* ?

@xabbuh
Copy link
Member

xabbuh commented May 6, 2024

Yes, bugfix will be part of the next patch releases for Symfony 5.4, 6.4 and 7.0.

@alexandre-le-borgne
Copy link

And for the 3rd time for me, rollback to v6.4.3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants