diff options
| author | Stanislav Malyshev <stas@php.net> | 2012-05-10 23:58:10 -0700 |
|---|---|---|
| committer | Stanislav Malyshev <stas@php.net> | 2012-05-13 14:40:44 -0700 |
| commit | 9344bf193c6e35c8706923953f3e63bb01cc05ed (patch) | |
| tree | 8aa98b676f52af23e1f478ae8f606a5887348ec3 /Zend/zend_operators.c | |
| parent | 58482206f5e101ea8a1768375439021891c84bdf (diff) | |
| download | php-git-9344bf193c6e35c8706923953f3e63bb01cc05ed.tar.gz | |
fix bug #54547
Diffstat (limited to 'Zend/zend_operators.c')
| -rw-r--r-- | Zend/zend_operators.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index a849cccf13..8d4baa6ac8 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -2035,15 +2035,30 @@ ZEND_API int zend_binary_zval_strncasecmp(zval *s1, zval *s2, zval *s3) /* {{{ * ZEND_API void zendi_smart_strcmp(zval *result, zval *s1, zval *s2) /* {{{ */ { int ret1, ret2; + int oflow1, oflow2; long lval1, lval2; double dval1, dval2; - if ((ret1=is_numeric_string(Z_STRVAL_P(s1), Z_STRLEN_P(s1), &lval1, &dval1, 0)) && - (ret2=is_numeric_string(Z_STRVAL_P(s2), Z_STRLEN_P(s2), &lval2, &dval2, 0))) { + if ((ret1=is_numeric_string_ex(Z_STRVAL_P(s1), Z_STRLEN_P(s1), &lval1, &dval1, 0, &oflow1)) && + (ret2=is_numeric_string_ex(Z_STRVAL_P(s2), Z_STRLEN_P(s2), &lval2, &dval2, 0, &oflow2))) { + if (oflow1 != 0 && oflow1 == oflow2 && dval1 - dval2 == 0.) { + /* both values are integers overflown to the same side, and the + * double comparison may have resulted in crucial accuracy lost */ + goto string_cmp; + } if ((ret1==IS_DOUBLE) || (ret2==IS_DOUBLE)) { if (ret1!=IS_DOUBLE) { + if (oflow2) { + /* 2nd operand is integer > LONG_MAX (oflow2==1) or < LONG_MIN (-1) */ + ZVAL_LONG(result, -1 * oflow2); + return; + } dval1 = (double) lval1; } else if (ret2!=IS_DOUBLE) { + if (oflow1) { + ZVAL_LONG(result, oflow1); + return; + } dval2 = (double) lval2; } else if (dval1 == dval2 && !zend_finite(dval1)) { /* Both values overflowed and have the same sign, |
