Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 3c9f914

Browse filesBrowse files
committed
fix invalid float denormalization without decimal part
1 parent 6c33afc commit 3c9f914
Copy full SHA for 3c9f914

File tree

2 files changed

+13
-0
lines changed
Filter options

2 files changed

+13
-0
lines changed

‎src/Symfony/Component/Serializer/Normalizer/ScalarDenormalizer.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Serializer/Normalizer/ScalarDenormalizer.php
+12Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Symfony\Component\Serializer\Normalizer;
1313

14+
use Symfony\Component\PropertyInfo\Type;
15+
use Symfony\Component\Serializer\Encoder\JsonEncoder;
1416
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
1517
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
1618

@@ -32,6 +34,16 @@ public function denormalize($data, string $type, string $format = null, array $c
3234
throw new InvalidArgumentException(sprintf('Data expected to be of one of the types in "%s" ("%s" given).', implode(', ', array_keys(self::SCALAR_TYPES)), get_debug_type($data)));
3335
}
3436

37+
// JSON only has a Number type corresponding to both int and float PHP types.
38+
// PHP's json_encode, JavaScript's JSON.stringify, Go's json.Marshal as well as most other JSON encoders convert
39+
// floating-point numbers like 12.0 to 12 (the decimal part is dropped when possible).
40+
// PHP's json_decode automatically converts Numbers without a decimal part to integers.
41+
// To circumvent this behavior, integers are converted to floats when denormalizing JSON based formats and when
42+
// a float is expected.
43+
if (Type::BUILTIN_TYPE_FLOAT === $type && \is_int($data) && false !== strpos($format, JsonEncoder::FORMAT)) {
44+
return (float) $data;
45+
}
46+
3547
if (!('is_'.$type)($data)) {
3648
throw new NotNormalizableValueException(sprintf('Data expected to be of type "%s" ("%s" given).', $type, get_debug_type($data)));
3749
}

‎src/Symfony/Component/Serializer/Tests/SerializerTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Serializer/Tests/SerializerTest.php
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,7 @@ public function testDeserializeScalar()
564564
$this->assertTrue($serializer->deserialize('true', 'bool', 'json'));
565565
$this->assertSame(3.14, $serializer->deserialize('3.14', 'float', 'json'));
566566
$this->assertSame(3.14, $serializer->deserialize('31.4e-1', 'float', 'json'));
567+
$this->assertSame(3.0, $serializer->deserialize('3', 'float', 'json')); // '3' === json_encode(3.0)
567568
$this->assertSame(' spaces ', $serializer->deserialize('" spaces "', 'string', 'json'));
568569
$this->assertSame('@Ca$e%', $serializer->deserialize('"@Ca$e%"', 'string', 'json'));
569570
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.