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

Skip to content

[Serializer] Fix serialized path for non-scalar values #49525

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

Conversation

boenner
Copy link
Contributor

@boenner boenner commented Feb 24, 2023

Q A
Branch? 6.2
Bug fix? yes
New feature? no
Deprecations? no
Tickets Fix #49494
License MIT
Doc PR no

This relates to #49494 and #49225. When non-scalar values are normalized, they are normalized twice in the normalize() function:

if (null !== $attributeValue && !\is_scalar($attributeValue)) {
	$stack[$attribute] = $attributeValue;
}
$data = $this->updateData($data, $attribute, $attributeValue, $class, $format, $attributeContext, $attributesMetadata, $classMetadata);

and a bit later:

foreach ($stack as $attribute => $attributeValue) {
	...
	$data = $this->updateData($data, $attribute, $this->serializer->normalize($attributeValue, $format, $childContext), $class, $format, $attributeContext, $attributesMetadata, $classMetadata);
}

For non-scalar values with a SerializedPath annotation this leads to an exception because the serializer is trying to re-populate the path. Running updateData() only once fixes this, but breaks a couple of tests across the components as it changes the order of elements in the serialized string (non-scalar values will be pushed to the end). Other than the string comparisons, nothing seems to break. This was also an issue while reviewing the PR for the SerializedPath annotation (#43534 (comment)) and got reverted because of the potential BC break.

I'm not sure what benefit normalizing twice brings, so I added the test from @HonzaMatosik, changed the behavior in the normalizer and fixed the broken tests. If that's not the preferred solution here, I'd be ok with just eleminating the "The element you are trying to set is already populated" exception in the SerializedPath and allow overwriting values.

@carsonbot
Copy link

Hey!

I think @ThomasNunninger has recently worked with this code. Maybe they can help review this?

Cheers!

Carsonbot

@nicolas-grekas nicolas-grekas modified the milestones: 6.2, 5.4 Mar 31, 2023
@nicolas-grekas nicolas-grekas force-pushed the serializer-serializedpath-with-non-scalar-types branch from 561df12 to d82ec41 Compare March 31, 2023 09:05
Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

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

I updated the code to preserve the order.

@nicolas-grekas
Copy link
Member

Thank you @boenner.

@nicolas-grekas nicolas-grekas merged commit 4f2aaf9 into symfony:6.2 Mar 31, 2023
@fabpot fabpot mentioned this pull request Mar 31, 2023
nicolas-grekas added a commit that referenced this pull request Apr 14, 2023
…kalineskou)

This PR was merged into the 6.2 branch.

Discussion
----------

[Serializer] Fix serializer normalize attribute context

| Q             | A
| ------------- | ---
| Branch?       | 6.2 <!-- see below -->
| Bug fix?      | yes
| New feature?  | no <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tickets       | Fix #... <!-- prefix each issue number with "Fix #", no need to create an issue if none exists, explain below instead -->
| License       | MIT
| Doc PR        | symfony/symfony-docs#... <!-- required for new features -->
<!--
Replace this notice by a short README for your feature/bugfix.
This will help reviewers and should be a good start for the documentation.

Additionally (see https://symfony.com/releases):
 - Always add tests and ensure they pass.
 - Bug fixes must be submitted against the lowest maintained branch where they apply
   (lowest branches are regularly merged to upper ones so they get the fixes too).
 - Features and deprecations must be submitted against the latest branch.
 - For new features, provide some code snippets to help understand usage.
 - Changelog entry should follow https://symfony.com/doc/current/contributing/code/conventions.html#writing-a-changelog-entry
 - Never break backward compatibility (see https://symfony.com/bc).
-->

Before 6.2.8 property attribute`#[Context(normalizationContext: [AbstractObjectNormalizer::SKIP_NULL_VALUES => true])]` was working correctly

Before this PR #49525 `updateData` was using the `$attributeContext` but it got changed to using `$context` (which ignored the attribute context)

Fixed the `testNormalizeUsesContextAttributeForPropertiesInConstructorWithSerializedPath` test also since `Context` attribute class was never used in the file (the date was still in `d-m-Y` format when the format key was `m-d-Y`)

Would have ported it to 5.4, but it was not added in that branch.
Latest commit for this file in 5.4 https://github.com/symfony/symfony/blob/6ae4ac9b9f46203b3ebae3c4c52edd546709bdb1/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php#L205

Commits
-------

942a184 Fix serializer normalize attribute context
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants