Create an entity with a (virtual) property with a union (return) type definition (ex: function getValue(): int|string|bool|float)
Serialize the entity/property to JSON and return int(1) from getValue(). Expect int(1) in the serialized data
Serializer will detect a boolean value instead of an int and serialize bool(true)
Expected Result
For serialization, the returned types should be handled strict. So if an int(1) is returned, it should be int(1) and not bool(true)
Actual Result
int(1) is detected as primitive type bool and will get serialized as bool
Related Code
UnionHandler::testPrimitive()
TypePropertiesDriver::reorderTypes()
Problem
Despite the doc block on TypePropertiesDriver::reorderTypes(), which says int should come before bool, bool is sorted before int and will be tested first in UnionHandler::testPrimitive().
UnionHandler::testPrimitive() uses dynamic type conversions ((string) and (bool)) to check for the types. Therefore, int(1) will first get checked for bool and the dynamic conversion will result in a positive test.
(Sorry for not providing a pull request. But I'm not that experienced with the internals of the serializer compontent and such a change might have unexpected results I'm not aware of).
Change the type order in TypePropertiesDriver::reorderTypes(), so int is checked before bool
Make the checks in UnionHandler::testPrimitive() more strict, at least for serialization, since here we can expect exact types coming from the entities
@fabianerni thanks for report! The proposal for changes makes sense - could you please make pull request with the changes please? I can help in case of issues.
Steps required to reproduce the problem
function getValue(): int|string|bool|float
)int(1)
fromgetValue()
. Expectint(1)
in the serialized databool(true)
Expected Result
int(1)
is returned, it should beint(1)
and notbool(true)
Actual Result
int(1)
is detected as primitive type bool and will get serialized as boolRelated Code
UnionHandler::testPrimitive()
TypePropertiesDriver::reorderTypes()
Problem
TypePropertiesDriver::reorderTypes()
, which saysint
should come beforebool
,bool
is sorted beforeint
and will be tested first inUnionHandler::testPrimitive()
.UnionHandler::testPrimitive()
uses dynamic type conversions ((string)
and(bool)
) to check for the types. Therefore,int(1)
will first get checked for bool and the dynamic conversion will result in a positive test.Bug
Will result in a positive match for
bool
type forint(1)
andint(0)
(string) (bool) $data === (string) $data
https://github.com/schmittjoh/serializer/blob/master/src/Handler/UnionHandler.php#L134Suggested Solution
(Sorry for not providing a pull request. But I'm not that experienced with the internals of the serializer compontent and such a change might have unexpected results I'm not aware of).
TypePropertiesDriver::reorderTypes()
, so int is checked before boolUnionHandler::testPrimitive()
more strict, at least for serialization, since here we can expect exact types coming from the entities