From f90b877f4188dd24e0863456d175fc694a42f1c8 Mon Sep 17 00:00:00 2001 From: Andrea Faulds Date: Sat, 29 Nov 2014 02:13:20 +0000 Subject: [PATCH] Refactor ZEND_LONG_MAX/MIN checks into ZEND_DOUBLE_FITS_LONG() --- Zend/zend_API.c | 4 ++-- Zend/zend_API.h | 4 ++-- Zend/zend_operators.h | 12 +++++++++--- .../tests/strings/chunk_split_variation2.phpt | 4 ++-- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 04d7f8a23f2..57288c67090 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -407,7 +407,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons if (zend_isnan(d)) { return "long"; } - if (d > ZEND_LONG_MAX || d < ZEND_LONG_MIN) { + if (!ZEND_DOUBLE_FITS_LONG(d)) { if (c == 'L') { *p = (d > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN; } else { @@ -425,7 +425,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons if (zend_isnan(Z_DVAL_P(arg))) { return "long"; } - if (Z_DVAL_P(arg) > ZEND_LONG_MAX || Z_DVAL_P(arg) < ZEND_LONG_MIN) { + if (!ZEND_DOUBLE_FITS_LONG(Z_DVAL_P(arg))) { if (c == 'L') { *p = (Z_DVAL_P(arg) > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN; } else { diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 701c1811ec7..1886f13842c 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -1067,7 +1067,7 @@ static zend_always_inline int _z_param_long(zval *arg, zend_long *dest, zend_boo if (UNEXPECTED(zend_isnan(Z_DVAL_P(arg)))) { return 0; } - if (UNEXPECTED(Z_DVAL_P(arg) > ZEND_LONG_MAX || Z_DVAL_P(arg) < ZEND_LONG_MIN)) { + if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(Z_DVAL_P(arg)))) { /* Ironically, the strict parameter makes zpp *non*-strict here */ if (strict) { *dest = (Z_DVAL_P(arg) > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN; @@ -1086,7 +1086,7 @@ static zend_always_inline int _z_param_long(zval *arg, zend_long *dest, zend_boo if (UNEXPECTED(zend_isnan(d))) { return 0; } - if (UNEXPECTED(d > ZEND_LONG_MAX || d < ZEND_LONG_MIN)) { + if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(d))) { if (strict) { *dest = (d > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN; } else { diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index f95e856e684..9d290a1b066 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -89,6 +89,13 @@ ZEND_API zend_uchar _is_numeric_string_ex(const char *str, size_t length, zend_l END_EXTERN_C() +#if SIZEOF_ZEND_LONG == 4 +# define ZEND_DOUBLE_FITS_LONG(d) (!((d) > ZEND_LONG_MAX || (d) < ZEND_LONG_MIN)) +#else + /* >= as (double)ZEND_LONG_MAX is outside signed range */ +# define ZEND_DOUBLE_FITS_LONG(d) (!((d) >= ZEND_LONG_MAX || (d) < ZEND_LONG_MIN)) +#endif + #if ZEND_DVAL_TO_LVAL_CAST_OK static zend_always_inline zend_long zend_dval_to_lval(double d) { @@ -103,7 +110,7 @@ static zend_always_inline zend_long zend_dval_to_lval(double d) { if (UNEXPECTED(!zend_finite(d)) || UNEXPECTED(zend_isnan(d))) { return 0; - } else if (d > ZEND_LONG_MAX || d < ZEND_LONG_MIN) { + } else if (!ZEND_DOUBLE_FITS_LONG(d)) { double two_pow_32 = pow(2., 32.), dmod; @@ -122,8 +129,7 @@ static zend_always_inline zend_long zend_dval_to_lval(double d) { if (UNEXPECTED(!zend_finite(d)) || UNEXPECTED(zend_isnan(d))) { return 0; - /* >= as (double)ZEND_LONG_MAX is outside signed range */ - } else if (d >= ZEND_LONG_MAX || d < ZEND_LONG_MIN) { + } else if (!ZEND_DOUBLE_FITS_LONG(d)) { double two_pow_64 = pow(2., 64.), dmod; diff --git a/ext/standard/tests/strings/chunk_split_variation2.phpt b/ext/standard/tests/strings/chunk_split_variation2.phpt index 2e4eaae35a2..1503d520f45 100644 --- a/ext/standard/tests/strings/chunk_split_variation2.phpt +++ b/ext/standard/tests/strings/chunk_split_variation2.phpt @@ -100,8 +100,8 @@ Warning: chunk_split(): Chunk length should be greater than zero in %schunk_spli bool(false) -- Iteration 3 -- -Warning: chunk_split(): Chunk length should be greater than zero in %schunk_split_variation2.php on line %d -bool(false) +Warning: chunk_split() expects parameter 2 to be long, double given in %s on line %d +NULL -- Iteration 4 -- Warning: chunk_split(): Chunk length should be greater than zero in %schunk_split_variation2.php on line %d