From 28f002d978154670cdad271cc848c69d81060b4a Mon Sep 17 00:00:00 2001 From: Eriksen Costa Date: Sun, 8 Jul 2012 22:15:42 -0300 Subject: [PATCH] [Locale] fixed bug on the parsing of TYPE_INT64 integers in 32 bit and 64 bit environments, caused by PHP bug fix :) (closes #4718) --- .../Locale/Stub/StubNumberFormatter.php | 28 ++++++- .../Locale/Stub/StubNumberFormatterTest.php | 80 ++++++++++++++++--- 2 files changed, 96 insertions(+), 12 deletions(-) diff --git a/src/Symfony/Component/Locale/Stub/StubNumberFormatter.php b/src/Symfony/Component/Locale/Stub/StubNumberFormatter.php index 0890f0b4c7..2524892a05 100644 --- a/src/Symfony/Component/Locale/Stub/StubNumberFormatter.php +++ b/src/Symfony/Component/Locale/Stub/StubNumberFormatter.php @@ -819,6 +819,8 @@ class StubNumberFormatter * @param mixed $value The value to be converted * * @return int|float The converted value + * + * @see https://bugs.php.net/bug.php?id=59597 Bug #59597 */ private function getInt64Value($value) { @@ -827,11 +829,33 @@ class StubNumberFormatter } if (PHP_INT_SIZE !== 8 && ($value > self::$int32Range['positive'] || $value <= self::$int32Range['negative'])) { + // Bug #59597 was fixed on PHP 5.3.14 and 5.4.4 + // The negative PHP_INT_MAX was being converted to float + if ( + $value == self::$int32Range['negative'] && + ( + (version_compare(PHP_VERSION, '5.4.0', '<') && version_compare(PHP_VERSION, '5.3.14', '>=')) || + version_compare(PHP_VERSION, '5.4.4', '>=') + ) + ) { + return (int) $value; + } + return (float) $value; } - if (PHP_INT_SIZE === 8 && ($value > self::$int32Range['positive'] || $value < self::$int32Range['negative'])) { - $value = (-2147483648 - ($value % -2147483648)) * ($value / abs($value)); + if (PHP_INT_SIZE === 8) { + // Bug #59597 was fixed on PHP 5.3.14 and 5.4.4 + // A 32 bit integer was being generated instead of a 64 bit integer + if ( + ($value > self::$int32Range['positive'] || $value < self::$int32Range['negative']) && + ( + (version_compare(PHP_VERSION, '5.3.14', '<')) || + (version_compare(PHP_VERSION, '5.4.0', '>=') && version_compare(PHP_VERSION, '5.4.4', '<')) + ) + ) { + $value = (-2147483648 - ($value % -2147483648)) * ($value / abs($value)); + } } return (int) $value; diff --git a/tests/Symfony/Tests/Component/Locale/Stub/StubNumberFormatterTest.php b/tests/Symfony/Tests/Component/Locale/Stub/StubNumberFormatterTest.php index e775763aee..753ef602ad 100644 --- a/tests/Symfony/Tests/Component/Locale/Stub/StubNumberFormatterTest.php +++ b/tests/Symfony/Tests/Component/Locale/Stub/StubNumberFormatterTest.php @@ -806,10 +806,20 @@ class StubNumberFormatterTest extends LocaleTestCase $this->assertInternalType('integer', $parsedValue); $this->assertEquals(2147483647, $parsedValue); - // Look that the parsing of '-2,147,483,648' results in a float like the literal -2147483648 $parsedValue = $formatter->parse('-2,147,483,648', \NumberFormatter::TYPE_INT64); - $this->assertInternalType('float', $parsedValue); - $this->assertEquals(((float) -2147483647 - 1), $parsedValue); + + // Bug #59597 was fixed on PHP 5.3.14 and 5.4.4 + // The negative PHP_INT_MAX was being converted to float + if ( + (version_compare(PHP_VERSION, '5.4.0', '<') && version_compare(PHP_VERSION, '5.3.14', '>=')) || + version_compare(PHP_VERSION, '5.4.4', '>=') + ) { + $this->assertInternalType('int', $parsedValue); + } else { + $this->assertInternalType('float', $parsedValue); + } + + $this->assertEquals(-2147483648, $parsedValue); } public function testParseTypeInt64StubWith32BitIntegerInPhp64Bit() @@ -857,11 +867,31 @@ class StubNumberFormatterTest extends LocaleTestCase $parsedValue = $formatter->parse('2,147,483,648', \NumberFormatter::TYPE_INT64); $this->assertInternalType('integer', $parsedValue); - $this->assertEquals(-2147483647 - 1, $parsedValue, '->parse() TYPE_INT64 does not use true 64 bit integers, using only the 32 bit range.'); + + // Bug #59597 was fixed on PHP 5.3.14 and 5.4.4 + // A 32 bit integer was being generated instead of a 64 bit integer + if ( + (version_compare(PHP_VERSION, '5.3.14', '<')) || + (version_compare(PHP_VERSION, '5.4.0', '>=') && version_compare(PHP_VERSION, '5.4.4', '<')) + ) { + $this->assertEquals(-2147483648, $parsedValue, '->parse() TYPE_INT64 does not use true 64 bit integers, using only the 32 bit range (PHP < 5.3.14 and PHP < 5.4.4).'); + } else { + $this->assertEquals(2147483648, $parsedValue, '->parse() TYPE_INT64 uses true 64 bit integers (PHP >= 5.3.14 and PHP >= 5.4.4).'); + } $parsedValue = $formatter->parse('-2,147,483,649', \NumberFormatter::TYPE_INT64); $this->assertInternalType('integer', $parsedValue); - $this->assertEquals(2147483647, $parsedValue, '->parse() TYPE_INT64 does not use true 64 bit integers, using only the 32 bit range.'); + + // Bug #59597 was fixed on PHP 5.3.14 and 5.4.4 + // A 32 bit integer was being generated instead of a 64 bit integer + if ( + (version_compare(PHP_VERSION, '5.3.14', '<')) || + (version_compare(PHP_VERSION, '5.4.0', '>=') && version_compare(PHP_VERSION, '5.4.4', '<')) + ) { + $this->assertEquals(2147483647, $parsedValue, '->parse() TYPE_INT64 does not use true 64 bit integers, using only the 32 bit range (PHP < 5.3.14 and PHP < 5.4.4).'); + } else { + $this->assertEquals(-2147483649, $parsedValue, '->parse() TYPE_INT64 uses true 64 bit integers (PHP >= 5.3.14 and PHP >= 5.4.4).'); + } } // Intl Tests @@ -877,10 +907,20 @@ class StubNumberFormatterTest extends LocaleTestCase $this->assertInternalType('integer', $parsedValue); $this->assertEquals(2147483647, $parsedValue); - // Look that the parsing of '-2,147,483,648' results in a float like the literal -2147483648 $parsedValue = $formatter->parse('-2,147,483,648', \NumberFormatter::TYPE_INT64); - $this->assertInternalType('float', $parsedValue); - $this->assertEquals(((float) -2147483647 - 1), $parsedValue); + + // Bug #59597 was fixed on PHP 5.3.14 and 5.4.4 + // The negative PHP_INT_MAX was being converted to float. + if ( + (version_compare(PHP_VERSION, '5.4.0', '<') && version_compare(PHP_VERSION, '5.3.14', '>=')) || + version_compare(PHP_VERSION, '5.4.4', '>=') + ) { + $this->assertInternalType('int', $parsedValue); + } else { + $this->assertInternalType('float', $parsedValue); + } + + $this->assertEquals(-2147483648, $parsedValue); } public function testParseTypeInt64IntlWith32BitIntegerInPhp64Bit() @@ -931,11 +971,31 @@ class StubNumberFormatterTest extends LocaleTestCase $parsedValue = $formatter->parse('2,147,483,648', \NumberFormatter::TYPE_INT64); $this->assertInternalType('integer', $parsedValue); - $this->assertEquals(-2147483647 - 1, $parsedValue, '->parse() TYPE_INT64 does not use true 64 bit integers, using only the 32 bit range.'); + + // Bug #59597 was fixed on PHP 5.3.14 and 5.4.4 + // A 32 bit integer was being generated instead of a 64 bit integer + if ( + (version_compare(PHP_VERSION, '5.3.14', '<')) || + (version_compare(PHP_VERSION, '5.4.0', '>=') && version_compare(PHP_VERSION, '5.4.4', '<')) + ) { + $this->assertEquals(-2147483648, $parsedValue, '->parse() TYPE_INT64 does not use true 64 bit integers, using only the 32 bit range (PHP < 5.3.14 and PHP < 5.4.4).'); + } else { + $this->assertEquals(2147483648, $parsedValue, '->parse() TYPE_INT64 uses true 64 bit integers (PHP >= 5.3.14 and PHP >= 5.4.4).'); + } $parsedValue = $formatter->parse('-2,147,483,649', \NumberFormatter::TYPE_INT64); $this->assertInternalType('integer', $parsedValue); - $this->assertEquals(2147483647, $parsedValue, '->parse() TYPE_INT64 does not use true 64 bit integers, using only the 32 bit range.'); + + // Bug #59597 was fixed on PHP 5.3.14 and 5.4.4 + // A 32 bit integer was being generated instead of a 64 bit integer + if ( + (version_compare(PHP_VERSION, '5.3.14', '<')) || + (version_compare(PHP_VERSION, '5.4.0', '>=') && version_compare(PHP_VERSION, '5.4.4', '<')) + ) { + $this->assertEquals(2147483647, $parsedValue, '->parse() TYPE_INT64 does not use true 64 bit integers, using only the 32 bit range (PHP < 5.3.14 and PHP < 5.4.4).'); + } else { + $this->assertEquals(-2147483649, $parsedValue, '->parse() TYPE_INT64 uses true 64 bit integers (PHP >= 5.3.14 and PHP >= 5.4.4).'); + } } /**