ID:               42868
 User updated by:  zoe dot slattery at googlemail dot com
 Reported By:      zoe dot slattery at googlemail dot com
 Status:           Open
 Bug Type:         Scripting Engine problem
 Operating System: Linux/Windows/OSX
 PHP Version:      5CVS-2007-10-05 (snap)
 New Comment:

Patch without tabs at:
http://www.pastebin.ca/768695

Or for raw file:
http://www.pastebin.ca/raw/768695


Previous Comments:
------------------------------------------------------------------------

[2007-11-08 17:11:42] zoe dot slattery at googlemail dot com

Following Andy W's comments, the patch is here:
http://www.pastebin.ca/766125

The test case is here:
http://www.pastebin.ca/766128

------------------------------------------------------------------------

[2007-11-08 10:23:04] zoe dot slattery at googlemail dot com

Here is a fix and a test. I've tested on Mac and Linux (32). I can't
test the Win64 behaviour. 

There are a number of tests which fail on Linux/Mac - but there are all
recent tests and were passing the wrong behaviour. I'll fix them if this
patch gets committed.

#P php53_dev
Index: Zend/zend_operators.c
===================================================================
RCS file: /repository/ZendEngine2/zend_operators.c,v
retrieving revision 1.208.2.4.2.23.2.2
diff -u -r1.208.2.4.2.23.2.2 zend_operators.c
--- Zend/zend_operators.c       29 Oct 2007 14:36:55 -0000     
1.208.2.4.2.23.2.2
+++ Zend/zend_operators.c       8 Nov 2007 10:09:10 -0000
@@ -185,21 +185,37 @@
                                break;                                 
                                                                       
\
                }                                                      
                                                                        
       \
        }
-
+#define MAX_UNSIGNED_INT ((double) LONG_MAX * 2) + 1
 #ifdef _WIN64
 # define DVAL_TO_LVAL(d, l) \
        if ((d) > LONG_MAX) { \
-               (l) = (long)(unsigned long)(__int64) (d); \
+                if ((d) > MAX_UNSIGNED_INT) { \
+                        (l) = LONG_MAX; \
+                } else { \
+                       (l) = (long)(unsigned long)(__int64) (d); \
+               } \
        } else { \
-               (l) = (long) (d); \
+                if((d) < LONG_MIN) { \
+                        (l) = LONG_MIN; \
+                } else { \
+                        (l) = (long) (d); \
+                } \
        }
 #else
 # define DVAL_TO_LVAL(d, l) \
-       if ((d) > LONG_MAX) { \
-               (l) = (unsigned long) (d); \
-       } else { \
-               (l) = (long) (d); \
-       }
+        if ((d) > LONG_MAX) { \
+                if ((d) > MAX_UNSIGNED_INT) { \
+                        (l) = LONG_MAX; \
+                } else { \
+                        (l) = (unsigned long) (d); \
+                } \
+        } else { \
+                if((d) < LONG_MIN) { \
+                if((d) < LONG_MIN) { \
+                        (l) = LONG_MIN; \
+                } else { \
+                        (l) = (long) (d); \
+                } \
+        }
 #endif

 #define zendi_convert_to_long(op, holder, result)   

Here is a PHPT test case that can be used to verify the fix:

--TEST--
Test intval() function : testsing cast of float to int on 32 bit
systems
--SKIPIF--
<?php
if (PHP_INT_SIZE != 4) die("skip this test is for 32bit platform
only");
?>
--FILE--
<?php
/* Prototype  : proto int intval(mixed var [, int base])
 * Description: Get the integer value of a variable using the optional
base for the conversion
 * Source code: ext/standard/type.c
 * Alias to functions:
 */

/*
 * A test to verify expected behaviour when floats are cast to
integers
 */

echo "*** Testing intval() : float to int ***\n";


// Initialise all required variables
$var = array();
$var[0] = PHP_INT_MAX + 1;
$var[1] = PHP_INT_MAX + 2;
$var[2] = PHP_INT_MAX + 3;
$var[3] = PHP_INT_MAX * 2 - 1;
$var[4] = PHP_INT_MAX * 2;
$var[5] = PHP_INT_MAX * 2 + 1;
$var[6] = PHP_INT_MAX * 2 + 2;
$var[7] = PHP_INT_MAX * 2 + 3;
$var[8] = -PHP_INT_MAX - 2;
$var[9] = -PHP_INT_MAX - 1;
$var[10] = -PHP_INT_MAX;
$var[11] = -PHP_INT_MAX + 1;

foreach ($var as $val) {
        var_dump( intval($val) );
}

echo "Done";
?>
--EXPECTF--
*** Testing intval() : float to int ***
int(-2147483648)
int(-2147483647)
int(-2147483646)
int(-3)
int(-2)
int(-1)
int(2147483647)
int(2147483647)
int(-2147483648)
int(-2147483648)
int(-2147483647)
Done

------------------------------------------------------------------------

[2007-11-02 12:13:22] zoe dot slattery at googlemail dot com

Just in case anyone is looking at this, I've been working with Andy
Wharmby on trying to find a better way to fix than the one I proposed.
If we can find a better fix it will be something that I will want to
test a lot, so may take a couple of weeks.

------------------------------------------------------------------------

[2007-11-01 09:30:01] zoe dot slattery at googlemail dot com

Sorry - fixed now I hope

------------------------------------------------------------------------

[2007-10-31 22:56:02] [EMAIL PROTECTED]

Could you please fix the summary line? Plain "zoe" is not very
descriptive. :)

------------------------------------------------------------------------

The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
    http://bugs.php.net/42868

-- 
Edit this bug report at http://bugs.php.net/?id=42868&edit=1

Reply via email to