summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrea Faulds <ajf@ajf.me>2014-11-29 02:13:20 +0000
committerAndrea Faulds <ajf@ajf.me>2014-11-29 02:13:20 +0000
commitf90b877f4188dd24e0863456d175fc694a42f1c8 (patch)
tree3ba58a66ba63d305c3aec43619242ed2431612a4
parentd19ce51854a94d9da3f5ff24ea965928ed520688 (diff)
downloadphp-git-f90b877f4188dd24e0863456d175fc694a42f1c8.tar.gz
Refactor ZEND_LONG_MAX/MIN checks into ZEND_DOUBLE_FITS_LONG()
-rw-r--r--Zend/zend_API.c4
-rw-r--r--Zend/zend_API.h4
-rw-r--r--Zend/zend_operators.h12
-rw-r--r--ext/standard/tests/strings/chunk_split_variation2.phpt4
4 files changed, 15 insertions, 9 deletions
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index 04d7f8a23f..57288c6709 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 701c1811ec..1886f13842 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 f95e856e68..9d290a1b06 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 2e4eaae35a..1503d520f4 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