8000 XmlEncoder: unexpected type of decoded float attributes which start with zero · Issue #38666 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content
XmlEncoder: unexpected type of decoded float attributes which start with zero #38666
Closed
@marcin-kruk

Description

@marcin-kruk

Symfony version(s) affected: 3.4

Description
If an XML attribute contains a positive float value which starts with 0, e.g. 0.123, XmlEncoder will decode it as a string.
If a float value starts with some other number, or is negative, then it is decoded as a float.

How to reproduce

<?php
require_once __DIR__.'/vendor/autoload.php';
use Symfony\Component\Serializer\Encoder\XmlEncoder;

$encoder = new XmlEncoder();

$xml = '<document value="0.123">...</document>';
$result = $encoder->decode($xml, 'xml');
var_dump($result);
// array(2) {
//   ["@value"]=>
//   string(5) "0.123"        <-- a float was expected, but it's a string
//   ["#"]=>
//   string(3) "..."
// }

Note that:

$xml = '<document value="1.123">...</document>';
$result = $encoder->decode($xml, 'xml');
var_dump($result);
// array(2) {
//   ["@value"]=>
//   float(1.123)        <-- float, as expected
//   ["#"]=>
//   string(3) "..."
// }

$xml = '<document value="-1.123">...</document>';
$result = $encoder->decode($xml, 'xml');
var_dump($result);
// array(2) {
//   ["@value"]=>
//   float(-1.123)        <-- negative values are also fine
//   ["#"]=>
//   string(3) "..."
// }

$xml = '<document value="-0.123">...</document>';
$result = $encoder->decode($xml, 'xml');
var_dump($result);
// array(2) {
//   ["@value"]=>
//   float(-0.123)        <-- ...even if negative value starts with 0
//   ["#"]=>
//   string(3) "..."
// }

Possible Solution
It looks like this behaviour was introduced in #32438 (as suggested here).
The naive approach would be to just extend the added check with the "but zero is not followed by a dot" condition, like in #38669.
Seems to work, but it feels like a nasty workaround, not a proper solution. And probably someone will find another case where it fails to produce a reasonable result.
Also, this section of code, i.e. trying to decode floats, has already been changed and fixed several times before (#22478, 8f6e67d and #32438), so it's not that easy to get it right and consider all edge cases. Maybe it would be better to try a different approach, something like #36482 or similar?
Btw, I assume we don't want to support comma as decimal separator.

Additional context
Normally I would say it's a limitation of the XmlEncoder, but returning a string only for floats which start with zero - it might be super confusing and difficult to debug.
For example (actually, that's how I found it), if you have a method which accepts floats (type hinting it) and receives as arguments values decoded by XmlEncoder, and the XML data looks like this:

...
<foo bar="1.9558"/>
<foo bar="25.653"/>
<foo bar="7.4615"/>
<foo bar="0.86828"/>
<foo bar="317.62"/>
...

The process will be sometimes failing, but it will look very randomly. Looking at the data, everything seems to be valid.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0