Skip to content

Commit eb2a18e

Browse files
bug #30063 [Form] don't lose int precision with not needed type casts (xabbuh)
This PR was merged into the 3.4 branch. Discussion ---------- [Form] don't lose int precision with not needed type casts | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #26795 | License | MIT | Doc PR | Commits ------- 72136f1 don't lose int precision with not needed type casts
2 parents 68b4825 + 72136f1 commit eb2a18e

File tree

3 files changed

+62
-3
lines changed

3 files changed

+62
-3
lines changed

src/Symfony/Component/Form/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformer.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,12 @@ public function reverseTransform($value)
4444

4545
return null !== $result ? (int) $result : null;
4646
}
47+
48+
/**
49+
* @internal
50+
*/
51+
protected function castParsedValue($value)
52+
{
53+
return $value;
54+
}
4755
}

src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,7 @@ public function reverseTransform($value)
181181
throw new TransformationFailedException('I don\'t have a clear idea what infinity looks like');
182182
}
183183

184-
if (\is_int($result) && $result === (int) $float = (float) $result) {
185-
$result = $float;
186-
}
184+
$result = $this->castParsedValue($result);
187185

188186
if (false !== $encoding = mb_detect_encoding($value, null, true)) {
189187
$length = mb_strlen($value, $encoding);
@@ -228,6 +226,18 @@ protected function getNumberFormatter()
228226
return $formatter;
229227
}
230228

229+
/**
230+
* @internal
231+
*/
232+
protected function castParsedValue($value)
233+
{
234+
if (\is_int($value) && $value === (int) $float = (float) $value) {
235+
return $float;
236+
}
237+
238+
return $value;
239+
}
240+
231241
/**
232242
* Rounds a number according to the configured scale and rounding mode.
233243
*

src/Symfony/Component/Form/Tests/Extension/Core/Type/IntegerTypeTest.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,45 @@ public function testSubmitNullUsesDefaultEmptyData($emptyData = '10', $expectedD
5050
$this->assertSame($expectedData, $form->getNormData());
5151
$this->assertSame($expectedData, $form->getData());
5252
}
53+
54+
public function testSubmittedLargeIntegersAreNotCastToFloat()
55+
{
56+
if (4 === \PHP_INT_SIZE) {
57+
$this->markTestSkipped('This test requires a 64bit PHP.');
58+
}
59+
60+
$form = $this->factory->create(static::TESTED_TYPE);
61+
$form->submit('201803221011791');
62+
63+
$this->assertSame(201803221011791, $form->getData());
64+
$this->assertSame('201803221011791', $form->getViewData());
65+
}
66+
67+
public function testTooSmallIntegersAreNotValid()
68+
{
69+
if (4 === \PHP_INT_SIZE) {
70+
$min = '-2147483649';
71+
} else {
72+
$min = '-9223372036854775808';
73+
}
74+
75+
$form = $this->factory->create(static::TESTED_TYPE);
76+
$form->submit($min);
77+
78+
$this->assertFalse($form->isSynchronized());
79+
}
80+
81+
public function testTooGreatIntegersAreNotValid()
82+
{
83+
if (4 === \PHP_INT_SIZE) {
84+
$max = '2147483648';
85+
} else {
86+
$max = '9223372036854775808';
87+
}
88+
89+
$form = $this->factory->create(static::TESTED_TYPE);
90+
$form->submit($max);
91+
92+
$this->assertFalse($form->isSynchronized());
93+
}
5394
}

0 commit comments

Comments
 (0)