bug #31031 [Serializer] MetadataAwareNameConverter: Do not assume that property names are strings (soyuka)

This PR was merged into the 4.2 branch.

Discussion
----------

[Serializer]  MetadataAwareNameConverter: Do not assume that property names are strings

| Q             | A
| ------------- | ---
| Branch?       | 4.2 (class introduced in v4.2.3)
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no     <!-- see https://symfony.com/bc -->
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | https://github.com/api-platform/core/pull/2709
| License       | MIT
| Doc PR        | n/a

When this class was introduced, there was an assumption made about the type of `propertyNames` and therefore a `: ?string` return type was introduced in the fallbacks/normalization private methods. Because symfony doesn't use strict mode yet (compatibility issues with php IIRC), when using a non-string property name (for example the integer `0` which is a valid property name in an array), it will convert the integer to a string.
This is not good, especially if you have a name converter that returns the given property name (ie no transformation) you'll have it's type changed which isn't correct.

I've discovered this bug while working on adding this name converter in api platform (https://github.com/api-platform/core/pull/2709).

Commits
-------

af1e136ca0 MetadataAwareNameConverter: Do not assume that property names are strings
This commit is contained in:
Fabien Potencier 2019-04-10 12:55:09 +02:00
commit de53bd6c67
2 changed files with 6 additions and 4 deletions

View File

@ -69,7 +69,7 @@ final class MetadataAwareNameConverter implements AdvancedNameConverterInterface
return self::$denormalizeCache[$class][$propertyName] ?? $this->denormalizeFallback($propertyName, $class, $format, $context);
}
private function getCacheValueForNormalization(string $propertyName, string $class): ?string
private function getCacheValueForNormalization($propertyName, string $class)
{
if (!$this->metadataFactory->hasMetadataFor($class)) {
return null;
@ -83,12 +83,12 @@ final class MetadataAwareNameConverter implements AdvancedNameConverterInterface
return $attributesMetadata[$propertyName]->getSerializedName() ?? null;
}
private function normalizeFallback(string $propertyName, string $class = null, string $format = null, array $context = []): string
private function normalizeFallback($propertyName, string $class = null, string $format = null, array $context = [])
{
return $this->fallbackNameConverter ? $this->fallbackNameConverter->normalize($propertyName, $class, $format, $context) : $propertyName;
}
private function getCacheValueForDenormalization(string $propertyName, string $class): ?string
private function getCacheValueForDenormalization($propertyName, string $class)
{
if (!isset(self::$attributesMetadataCache[$class])) {
self::$attributesMetadataCache[$class] = $this->getCacheValueForAttributesMetadata($class);
@ -97,7 +97,7 @@ final class MetadataAwareNameConverter implements AdvancedNameConverterInterface
return self::$attributesMetadataCache[$class][$propertyName] ?? null;
}
private function denormalizeFallback(string $propertyName, string $class = null, string $format = null, array $context = []): string
private function denormalizeFallback($propertyName, string $class = null, string $format = null, array $context = [])
{
return $this->fallbackNameConverter ? $this->fallbackNameConverter->denormalize($propertyName, $class, $format, $context) : $propertyName;
}

View File

@ -102,6 +102,7 @@ final class MetadataAwareNameConverterTest extends TestCase
['foo', 'baz'],
['bar', 'qux'],
['quux', 'quux'],
[0, 0],
];
}
@ -111,6 +112,7 @@ final class MetadataAwareNameConverterTest extends TestCase
['foo', 'baz'],
['bar', 'qux'],
['quux', 'QUUX'],
[0, 0],
];
}
}