Skip to content

Commit 1538e02

Browse files
committed
Merge branch '3.1' into 3.2
* 3.1: [TwigBundle] fixed usage when Templating is not installed [Validator] Check cascasdedGroups for being countable [Cache] Add changelog [Filesystem] Check that the directory is writable after created it in dumpFile() [HttpFoundation] Improved set cookie header tests [Serializer] int is valid when float is expected when deserializing JSON [Console] increased code coverage of Output classes Added missing headers in fixture files [Profiler][VarDumper] Fix minor color issue & duplicated selector
2 parents d821c0d + 16f167b commit 1538e02

File tree

2 files changed

+34
-5
lines changed

2 files changed

+34
-5
lines changed

Normalizer/AbstractObjectNormalizer.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Serializer\Normalizer;
1313

1414
use Symfony\Component\PropertyAccess\Exception\InvalidArgumentException;
15+
use Symfony\Component\Serializer\Encoder\JsonEncoder;
1516
use Symfony\Component\Serializer\Exception\CircularReferenceException;
1617
use Symfony\Component\Serializer\Exception\LogicException;
1718
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
@@ -260,6 +261,16 @@ private function validateAndDenormalize($currentClass, $attribute, $data, $forma
260261
}
261262
}
262263

264+
// JSON only has a Number type corresponding to both int and float PHP types.
265+
// PHP's json_encode, JavaScript's JSON.stringify, Go's json.Marshal as well as most other JSON encoders convert
266+
// floating-point numbers like 12.0 to 12 (the decimal part is dropped when possible).
267+
// PHP's json_decode automatically converts Numbers without a decimal part to integers.
268+
// To circumvent this behavior, integers are converted to floats when denormalizing JSON based formats and when
269+
// a float is expected.
270+
if (Type::BUILTIN_TYPE_FLOAT === $builtinType && is_int($data) && false !== strpos($format, JsonEncoder::FORMAT)) {
271+
return (float) $data;
272+
}
273+
263274
if (call_user_func('is_'.$builtinType, $data)) {
264275
return $data;
265276
}

Tests/Normalizer/ObjectNormalizerTest.php

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -580,11 +580,21 @@ public function testDenomalizeRecursive()
580580
'inners' => array(array('foo' => 1), array('foo' => 2)),
581581
), ObjectOuter::class);
582582

583-
$this->assertEquals('foo', $obj->getInner()->foo);
584-
$this->assertEquals('bar', $obj->getInner()->bar);
585-
$this->assertEquals('1988-01-21', $obj->getDate()->format('Y-m-d'));
586-
$this->assertEquals(1, $obj->getInners()[0]->foo);
587-
$this->assertEquals(2, $obj->getInners()[1]->foo);
583+
$this->assertSame('foo', $obj->getInner()->foo);
584+
$this->assertSame('bar', $obj->getInner()->bar);
585+
$this->assertSame('1988-01-21', $obj->getDate()->format('Y-m-d'));
586+
$this->assertSame(1, $obj->getInners()[0]->foo);
587+
$this->assertSame(2, $obj->getInners()[1]->foo);
588+
}
589+
590+
public function testAcceptJsonNumber()
591+
{
592+
$extractor = new PropertyInfoExtractor(array(), array(new PhpDocExtractor(), new ReflectionExtractor()));
593+
$normalizer = new ObjectNormalizer(null, null, null, $extractor);
594+
$serializer = new Serializer(array(new ArrayDenormalizer(), new DateTimeNormalizer(), $normalizer));
595+
596+
$this->assertSame(10.0, $serializer->denormalize(array('number' => 10), JsonNumber::class, 'json')->number);
597+
$this->assertSame(10.0, $serializer->denormalize(array('number' => 10), JsonNumber::class, 'jsonld')->number);
588598
}
589599

590600
/**
@@ -892,3 +902,11 @@ public function __construct($id, Unknown $unknown)
892902
{
893903
}
894904
}
905+
906+
class JsonNumber
907+
{
908+
/**
909+
* @var float
910+
*/
911+
public $number;
912+
}

0 commit comments

Comments
 (0)