php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #50970 force convert a string into int using (int) or intval() cause value truncate
Submitted: 2010-02-09 01:29 UTC Modified: 2010-02-21 01:43 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: zhangsilly at gmail dot com Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: 5.2.12 OS: Windows XP
Private report: No CVE-ID: None
 [2010-02-09 01:29 UTC] zhangsilly at gmail dot com
Description:
------------
use (int) or intval() to convert a string into integer in userland, if 
bigger than 2147483647, this will result a truncate, the value will 
always be 2147483647.

     but use zend_parse_parameters to parse the string as a long 
arguement, is do give the correct value in nagtive format



Reproduce code:
---------------
/** 
* assert failure 
* (int)3740925952 result is -554041344 
* (int)'3740925952' result is 2147483647 
*/ 
assert((int)3740925952 == (int)'3740925952'); 

Expected result:
----------------
assert should be succeed

Actual result:
--------------
assert failure

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-02-10 01:48 UTC] zhangsilly at gmail dot com
this is cause by strtol, used in the ZEND_API convert_to_long_base(zval 
*op, int base), which is defined in stdlib.h.

    strtol will always return LONG_MAX if the string stands for a number 
which is larger than LONG_MAX.

    I'am afraid no matter zend_parse_parameters and convert_to_long, the  
should have the same behavior.

    This whill cause a situation that when i pass a string which is 
readed from file or socket to long2ip, long2ip($str) is right but 
long2ip((int)$str) will be failed.
 [2010-02-12 17:36 UTC] jani@php.net
Please try using this snapshot:

  http://snaps.php.net/php5.2-latest.tar.gz
 
For Windows:

  http://windows.php.net/snapshots/

Works fine for me with Linux..
 [2010-02-16 13:37 UTC] zhangsilly at gmail dot com
Thanks for your reply. For I am having my spring festeval, now my computer does'nt have a compiler, I can't test it.

    But I do download the source from http://snaps.php.net/php5.2-latest.tar.gz  at 2010-02-16 21:19, chinese standard time, and check the source , I 'am sure the bug can be reproduced.

    See the file Zend/zend_operators.c, this bug is caused by the function:

ZEND_API void convert_to_long_base(zval *op, int base)
{
	char *strval;
	long tmp;

	switch (op->type) {
		case IS_NULL:
			op->value.lval = 0;
			break;
		case IS_RESOURCE: {
				TSRMLS_FETCH();

				zend_list_delete(op->value.lval);
			}
			/* break missing intentionally */
		case IS_BOOL:
		case IS_LONG:
			break;
		case IS_DOUBLE:
			DVAL_TO_LVAL(op->value.dval, op->value.lval);
			break;
		case IS_STRING:
			strval = op->value.str.val;
			op->value.lval = strtol(strval, NULL, base);
			STR_FREE(strval);
			break;

     See the enter point IS_STRING, it use strtol directly. The truncate was caused by the strtol. If you still use it directly, This bug will not be fixed.
 [2010-02-16 13:53 UTC] zhangsilly at gmail dot com
To jani:

   Your PHP works fine on linux. Is your OS 64bit?

   I 'am sure , On Windows 32Bit, both of strtol and atol will truncate the value.
 [2010-02-20 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2010-02-21 01:32 UTC] zhangsilly at gmail dot com
This bug is still exists in the svn version.

Hope you will test this code:

echo '3740925952' + 1; //output 3740925953
echo (int) '3740925952' + 1; // output 2147483648

This bug is unacceptable.
 [2010-02-21 01:43 UTC] rasmus@php.net
You need a true 64-bit OS if you want this to work.  The integer 
datatype in PHP is a long.  Your example works perfectly on 64-bit 
Linux.  We can't fix this on 32-bit without turning the basic integer 
datatype into some sort of arbitrary precision hack which would 
probably be an order of magnitude performance hit for basic integer 
math.  And frankly, the number of 32-bit web servers is falling at a 
rapid rate.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Thu Dec 04 06:00:01 2025 UTC