|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[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
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Thu Dec 04 06:00:01 2025 UTC |
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.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.