Przeglądaj źródła

merged branch eriksencosta/issue-4718 (PR #4794)

Commits
-------

28f002d [Locale] fixed bug on the parsing of TYPE_INT64 integers in 32 bit and 64 bit environments, caused by PHP bug fix :) (closes #4718)

Discussion
----------

[Locale] fixed bug on the parsing of TYPE_INT64 integers in 32 bit and 64 bit environments, caused by PHP bug fix

Bug fix: yes
Feature addition: no
Backwards compatibility break: no
Symfony2 tests pass: yes
Fixes the following tickets: #4718
License of the code: MIT

[![Build Status](https://secure.travis-ci.org/eriksencosta/symfony.png?branch=issue-4718)](http://travis-ci.org/eriksencosta/symfony)

Tests pass on PHP 5.3.3, 5.3.14 and 5.4.4 with ICU 4.2, 4.4 and 4.6 on 32 and 64 bit environments.
Fabien Potencier 13 lat temu
rodzic
commit
fd1d5e8c10

+ 26 - 2
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;

+ 70 - 10
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).');
+        }
     }
 
     /**