From 72136f1c0489c84a45396cad5e20da0fe7220bdb Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sat, 2 Feb 2019 11:09:54 +0100 Subject: [PATCH] don't lose int precision with not needed type casts --- .../IntegerToLocalizedStringTransformer.php | 8 ++++ .../NumberToLocalizedStringTransformer.php | 16 ++++++-- .../Extension/Core/Type/IntegerTypeTest.php | 41 +++++++++++++++++++ 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformer.php index 999e47391b57..51c3821f9e29 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformer.php @@ -44,4 +44,12 @@ public function reverseTransform($value) return null !== $result ? (int) $result : null; } + + /** + * @internal + */ + protected function castParsedValue($value) + { + return $value; + } } diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php index 638885e4226e..c6b278817c1f 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php @@ -181,9 +181,7 @@ public function reverseTransform($value) throw new TransformationFailedException('I don\'t have a clear idea what infinity looks like'); } - if (\is_int($result) && $result === (int) $float = (float) $result) { - $result = $float; - } + $result = $this->castParsedValue($result); if (false !== $encoding = mb_detect_encoding($value, null, true)) { $length = mb_strlen($value, $encoding); @@ -228,6 +226,18 @@ protected function getNumberFormatter() return $formatter; } + /** + * @internal + */ + protected function castParsedValue($value) + { + if (\is_int($value) && $value === (int) $float = (float) $value) { + return $float; + } + + return $value; + } + /** * Rounds a number according to the configured scale and rounding mode. * diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/IntegerTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/IntegerTypeTest.php index 273402aefeb3..5a9d195f272f 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/IntegerTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/IntegerTypeTest.php @@ -50,4 +50,45 @@ public function testSubmitNullUsesDefaultEmptyData($emptyData = '10', $expectedD $this->assertSame($expectedData, $form->getNormData()); $this->assertSame($expectedData, $form->getData()); } + + public function testSubmittedLargeIntegersAreNotCastToFloat() + { + if (4 === \PHP_INT_SIZE) { + $this->markTestSkipped('This test requires a 64bit PHP.'); + } + + $form = $this->factory->create(static::TESTED_TYPE); + $form->submit('201803221011791'); + + $this->assertSame(201803221011791, $form->getData()); + $this->assertSame('201803221011791', $form->getViewData()); + } + + public function testTooSmallIntegersAreNotValid() + { + if (4 === \PHP_INT_SIZE) { + $min = '-2147483649'; + } else { + $min = '-9223372036854775808'; + } + + $form = $this->factory->create(static::TESTED_TYPE); + $form->submit($min); + + $this->assertFalse($form->isSynchronized()); + } + + public function testTooGreatIntegersAreNotValid() + { + if (4 === \PHP_INT_SIZE) { + $max = '2147483648'; + } else { + $max = '9223372036854775808'; + } + + $form = $this->factory->create(static::TESTED_TYPE); + $form->submit($max); + + $this->assertFalse($form->isSynchronized()); + } }