@@ -2264,17 +2264,18 @@ static int compare_long_to_string(zend_long lval, zend_string *str) /* {{{ */
22642264 uint8_t type = is_numeric_string (ZSTR_VAL (str ), ZSTR_LEN (str ), & str_lval , & str_dval , 0 );
22652265
22662266 if (type == IS_LONG ) {
2267- return lval > str_lval ? 1 : lval < str_lval ? -1 : 0 ;
2267+ return ZEND_THREEWAY_COMPARE ( lval , str_lval ) ;
22682268 }
22692269
22702270 if (type == IS_DOUBLE ) {
22712271 return ZEND_THREEWAY_COMPARE ((double ) lval , str_dval );
22722272 }
22732273
2274- zend_string * lval_as_str = zend_long_to_str (lval );
2274+ char buf [MAX_LENGTH_OF_LONG + 1 ];
2275+ char * tmp = zend_print_long_to_buf (buf + sizeof (buf ) - 1 , lval );
2276+ size_t tmp_len = buf + sizeof (buf ) - 1 - tmp ;
22752277 int cmp_result = zend_binary_strcmp (
2276- ZSTR_VAL (lval_as_str ), ZSTR_LEN (lval_as_str ), ZSTR_VAL (str ), ZSTR_LEN (str ));
2277- zend_string_release (lval_as_str );
2278+ tmp , tmp_len , ZSTR_VAL (str ), ZSTR_LEN (str ));
22782279 return ZEND_NORMALIZE_BOOL (cmp_result );
22792280}
22802281/* }}} */
@@ -2295,10 +2296,12 @@ static int compare_double_to_string(double dval, zend_string *str) /* {{{ */
22952296 return ZEND_THREEWAY_COMPARE (dval , str_dval );
22962297 }
22972298
2298- zend_string * dval_as_str = zend_double_to_str (dval );
2299+ char buf [ZEND_DOUBLE_MAX_LENGTH ];
2300+ int precision = (int ) EG (precision );
2301+ zend_gcvt (dval , precision ? precision : 1 , '.' , 'E' , buf );
2302+ size_t tmp_len = strlen (buf );
22992303 int cmp_result = zend_binary_strcmp (
2300- ZSTR_VAL (dval_as_str ), ZSTR_LEN (dval_as_str ), ZSTR_VAL (str ), ZSTR_LEN (str ));
2301- zend_string_release (dval_as_str );
2304+ buf , tmp_len , ZSTR_VAL (str ), ZSTR_LEN (str ));
23022305 return ZEND_NORMALIZE_BOOL (cmp_result );
23032306}
23042307/* }}} */
@@ -3420,52 +3423,73 @@ ZEND_API bool ZEND_FASTCALL zendi_smart_streq(zend_string *s1, zend_string *s2)
34203423
34213424ZEND_API int ZEND_FASTCALL zendi_smart_strcmp (zend_string * s1 , zend_string * s2 ) /* {{{ */
34223425{
3423- uint8_t ret1 , ret2 ;
3424- int oflow1 , oflow2 ;
3426+ uint8_t ret1 = 0 , ret2 = 0 ;
3427+ int oflow1 = 0 , oflow2 = 0 ;
34253428 zend_long lval1 = 0 , lval2 = 0 ;
34263429 double dval1 = 0.0 , dval2 = 0.0 ;
34273430
3428- if ((ret1 = is_numeric_string_ex (s1 -> val , s1 -> len , & lval1 , & dval1 , false, & oflow1 , NULL )) &&
3429- (ret2 = is_numeric_string_ex (s2 -> val , s2 -> len , & lval2 , & dval2 , false, & oflow2 , NULL ))) {
3431+ if ((unsigned char )s1 -> val [0 ] > '9' && (unsigned char )s2 -> val [0 ] > '9' ) {
3432+ goto string_cmp ;
3433+ }
3434+
3435+ if (UNEXPECTED (s1 -> len == 0 || s2 -> len == 0 )) {
3436+ goto string_cmp ;
3437+ }
3438+
3439+ if ((unsigned char )s1 -> val [0 ] <= '9' ) {
3440+ ret1 = is_numeric_string_ex (s1 -> val , s1 -> len , & lval1 , & dval1 , false, & oflow1 , NULL );
3441+ }
3442+
3443+ if (!ret1 ) {
3444+ goto string_cmp ;
3445+ }
3446+
3447+ ret2 = ((unsigned char )s2 -> val [0 ] <= '9' )
3448+ ? is_numeric_string_ex (s2 -> val , s2 -> len , & lval2 , & dval2 , false, & oflow2 , NULL )
3449+ : 0 ;
3450+
3451+ if (!ret2 ) {
3452+ goto string_cmp ;
3453+ }
3454+
34303455#if ZEND_ULONG_MAX == 0xFFFFFFFF
3431- if (oflow1 != 0 && oflow1 == oflow2 && dval1 - dval2 == 0. &&
3432- ((oflow1 == 1 && dval1 > 9007199254740991. /*0x1FFFFFFFFFFFFF*/ )
3433- || (oflow1 == -1 && dval1 < -9007199254740991. ))) {
3456+ if (oflow1 != 0 && oflow1 == oflow2 && dval1 - dval2 == 0. &&
3457+ ((oflow1 == 1 && dval1 > 9007199254740991. /*0x1FFFFFFFFFFFFF*/ )
3458+ || (oflow1 == -1 && dval1 < -9007199254740991. ))) {
34343459#else
3435- if (oflow1 != 0 && oflow1 == oflow2 && dval1 - dval2 == 0. ) {
3460+ if (oflow1 != 0 && oflow1 == oflow2 && dval1 - dval2 == 0. ) {
34363461#endif
3437- /* both values are integers overflowed to the same side, and the
3438- * double comparison may have resulted in crucial accuracy lost */
3462+ /* both values are integers overflowed to the same side, and the
3463+ * double comparison may have resulted in crucial accuracy lost */
3464+ goto string_cmp ;
3465+ }
3466+
3467+ if ((ret1 == IS_DOUBLE ) || (ret2 == IS_DOUBLE )) {
3468+ if (ret1 != IS_DOUBLE ) {
3469+ if (oflow2 ) {
3470+ /* 2nd operand is integer > LONG_MAX (oflow2==1) or < LONG_MIN (-1) */
3471+ return -1 * oflow2 ;
3472+ }
3473+ dval1 = (double ) lval1 ;
3474+ } else if (ret2 != IS_DOUBLE ) {
3475+ if (oflow1 ) {
3476+ return oflow1 ;
3477+ }
3478+ dval2 = (double ) lval2 ;
3479+ } else if (dval1 == dval2 && !zend_finite (dval1 )) {
3480+ /* Both values overflowed and have the same sign,
3481+ * so a numeric comparison would be inaccurate */
34393482 goto string_cmp ;
34403483 }
3441- if ((ret1 == IS_DOUBLE ) || (ret2 == IS_DOUBLE )) {
3442- if (ret1 != IS_DOUBLE ) {
3443- if (oflow2 ) {
3444- /* 2nd operand is integer > LONG_MAX (oflow2==1) or < LONG_MIN (-1) */
3445- return -1 * oflow2 ;
3446- }
3447- dval1 = (double ) lval1 ;
3448- } else if (ret2 != IS_DOUBLE ) {
3449- if (oflow1 ) {
3450- return oflow1 ;
3451- }
3452- dval2 = (double ) lval2 ;
3453- } else if (dval1 == dval2 && !zend_finite (dval1 )) {
3454- /* Both values overflowed and have the same sign,
3455- * so a numeric comparison would be inaccurate */
3456- goto string_cmp ;
3457- }
3458- dval1 = dval1 - dval2 ;
3459- return ZEND_NORMALIZE_BOOL (dval1 );
3460- } else { /* they both have to be long's */
3461- return lval1 > lval2 ? 1 : (lval1 < lval2 ? -1 : 0 );
3462- }
3463- } else {
3464- int strcmp_ret ;
3465- string_cmp :
3466- strcmp_ret = zend_binary_strcmp (s1 -> val , s1 -> len , s2 -> val , s2 -> len );
3467- return ZEND_NORMALIZE_BOOL (strcmp_ret );
3484+ return ZEND_THREEWAY_COMPARE (dval1 , dval2 );
34683485 }
3486+
3487+ return ZEND_THREEWAY_COMPARE (lval1 , lval2 );
3488+
3489+ int strcmp_ret ;
3490+ string_cmp :
3491+ strcmp_ret = zend_binary_strcmp (s1 -> val , s1 -> len , s2 -> val , s2 -> len );
3492+ return ZEND_NORMALIZE_BOOL (strcmp_ret );
34693493}
34703494/* }}} */
34713495
0 commit comments