-
-
Notifications
You must be signed in to change notification settings - Fork 9.8k
Description
Symfony version(s) affected
6.4.x
Description
have a xml representation like this:
<cac:CommodityClassification>
<cbc:ItemClassificationCode listID="IB" listVersionID="88">0721-880X</cbc:ItemClassificationCode>
</cac:CommodityClassification>
ItemClassificationCode is represented by this class
class CodeType
{
public function __construct(
#[SerializedName('#')]
public string $value,
#[SerializedName('@listID')]
public ?string $listID = null,
#[SerializedName('@listAgencyID')]
public ?string $listAgencyID = null,
#[SerializedName('@listAgencyName')]
public ?string $listAgencyName = null,
#[SerializedName('@listName')]
public ?string $listName = null,
#[SerializedName('@listVersionID')]
public ?string $listVersionID = null,
#[SerializedName('@name')]
public ?string $name = null,
#[SerializedName('@languageID')]
public ?string $languageID = null,
#[SerializedName('@listURI')]
public ?string $listURI = null,
#[SerializedName('@listSchemeURI')]
public ?string $listSchemeURI = null
)
{}
}See that the type of listVersionID should be a string?
Now XmlEncoder assumes on decoding that the attribute could be an int:
symfony/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php
Lines 273 to 277 in 6864dbe
| if (false !== $val = filter_var($attr->nodeValue, \FILTER_VALIDATE_INT)) { | |
| $data['@'.$attr->nodeName] = $val; | |
| continue; | |
| } |
which then causes a crash in AbstractObjectNormalizer:
Symfony\Component\Serializer\Exception\NotNormalizableValueException: The type of the "listVersionID" attribute for class "UBL\UnqualifiedDataTypes\CodeType" must be one of "string" ("int" given).
There is a special case for reading string and turning it into float and other values.
But there is no case where it should be string instead
symfony/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php
Lines 466 to 510 in 6864dbe
| if (\is_string($data) && (XmlEncoder::FORMAT === $format || CsvEncoder::FORMAT === $format)) { | |
| if ('' === $data) { | |
| if (LegacyType::BUILTIN_TYPE_ARRAY === $builtinType) { | |
| return []; | |
| } | |
| if (LegacyType::BUILTIN_TYPE_STRING === $builtinType) { | |
| return ''; | |
| } | |
| // Don't return null yet because Object-types that come first may accept empty-string too | |
| $isNullable = $isNullable ?: $type->isNullable(); | |
| } | |
| switch ($builtinType) { | |
| case LegacyType::BUILTIN_TYPE_BOOL: | |
| // according to https://www.w3.org/TR/xmlschema-2/#boolean, valid representations are "false", "true", "0" and "1" | |
| if ('false' === $data || '0' === $data) { | |
| $data = false; | |
| } elseif ('true' === $data || '1' === $data) { | |
| $data = true; | |
| } else { | |
| throw NotNormalizableValueException::createForUnexpectedDataType(\sprintf('The type of the "%s" attribute for class "%s" must be bool ("%s" given).', $attribute, $currentClass, $data), $data, [LegacyType::BUILTIN_TYPE_BOOL], $context['deserialization_path'] ?? null); | |
| } | |
| break; | |
| case LegacyType::BUILTIN_TYPE_INT: | |
| if (ctype_digit(isset($data[0]) && '-' === $data[0] ? substr($data, 1) : $data)) { | |
| $data = (int) $data; | |
| } else { | |
| throw NotNormalizableValueException::createForUnexpectedDataType(\sprintf('The type of the "%s" attribute for class "%s" must be int ("%s" given).', $attribute, $currentClass, $data), $data, [LegacyType::BUILTIN_TYPE_INT], $context['deserialization_path'] ?? null); | |
| } | |
| break; | |
| case LegacyType::BUILTIN_TYPE_FLOAT: | |
| if (is_numeric($data)) { | |
| return (float) $data; | |
| } | |
| return match ($data) { | |
| 'NaN' => \NAN, | |
| 'INF' => \INF, | |
| '-INF' => -\INF, | |
| default => throw NotNormalizableValueException::createForUnexpectedDataType(\sprintf('The type of the "%s" attribute for class "%s" must be float ("%s" given).', $attribute, $currentClass, $data), $data, [LegacyType::BUILTIN_TYPE_FLOAT], $context['deserialization_path'] ?? null), | |
| }; | |
| } | |
| } |
How to reproduce
use this example xml:
<cac:CommodityClassification>
<cbc:ItemClassificationCode listID="IB" listVersionID="88">0721-880X</cbc:ItemClassificationCode>
</cac:CommodityClassification>
Possible Solution
No response
Additional Context
No response