Skip to content

Commit 0ea0b59

Browse files
Merge branch 'zppFailOnOverflow'
* zppFailOnOverflow: Fix MySQLi tests Fixed gd test Refactor ZEND_LONG_MAX/MIN checks into ZEND_DOUBLE_FITS_LONG() Fixed copy-and-paste error Fix more 32-bit tests Skip buncha tests on 32-bit skip simplexml skip posix 32-bit skip tests on 32-bit Fixes simplexml test Fixes posix tests Fixes iconv tests Marked tests as 32-bit Fixed more 32-bit tests Fixed some 32-bit tests Mark said ext/date tests as 32-bit only Fixed ext/date tests broken by zpp error on overflow Fixed broken tests Make zpp fail if NaN passed for int, or out-of-range float for non-capping int Conflicts: ext/date/tests/getdate_variation7.phpt ext/date/tests/localtime_variation3.phpt
2 parents de0afce + d5afeef commit 0ea0b59

File tree

85 files changed

+422
-371
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+422
-371
lines changed

Zend/zend_API.c

+18-14
Original file line numberDiff line numberDiff line change
@@ -404,14 +404,16 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons
404404
if ((type = is_numeric_string(Z_STRVAL_P(arg), Z_STRLEN_P(arg), p, &d, -1)) == 0) {
405405
return "long";
406406
} else if (type == IS_DOUBLE) {
407-
if (c == 'L') {
408-
if (d > ZEND_LONG_MAX) {
409-
*p = ZEND_LONG_MAX;
410-
break;
411-
} else if (d < ZEND_LONG_MIN) {
412-
*p = ZEND_LONG_MIN;
413-
break;
407+
if (zend_isnan(d)) {
408+
return "long";
409+
}
410+
if (!ZEND_DOUBLE_FITS_LONG(d)) {
411+
if (c == 'L') {
412+
*p = (d > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN;
413+
} else {
414+
return "long";
414415
}
416+
break;
415417
}
416418

417419
*p = zend_dval_to_lval(d);
@@ -420,14 +422,16 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons
420422
break;
421423

422424
case IS_DOUBLE:
423-
if (c == 'L') {
424-
if (Z_DVAL_P(arg) > ZEND_LONG_MAX) {
425-
*p = ZEND_LONG_MAX;
426-
break;
427-
} else if (Z_DVAL_P(arg) < ZEND_LONG_MIN) {
428-
*p = ZEND_LONG_MIN;
429-
break;
425+
if (zend_isnan(Z_DVAL_P(arg))) {
426+
return "long";
427+
}
428+
if (!ZEND_DOUBLE_FITS_LONG(Z_DVAL_P(arg))) {
429+
if (c == 'L') {
430+
*p = (Z_DVAL_P(arg) > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN;
431+
} else {
432+
return "long";
430433
}
434+
break;
431435
}
432436
case IS_NULL:
433437
case IS_FALSE:

Zend/zend_API.h

+19-8
Original file line numberDiff line numberDiff line change
@@ -1064,10 +1064,16 @@ static zend_always_inline int _z_param_long(zval *arg, zend_long *dest, zend_boo
10641064
if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) {
10651065
*dest = Z_LVAL_P(arg);
10661066
} else if (EXPECTED(Z_TYPE_P(arg) == IS_DOUBLE)) {
1067-
if (strict && UNEXPECTED(Z_DVAL_P(arg) > ZEND_LONG_MAX)) {
1068-
*dest = ZEND_LONG_MAX;
1069-
} else if (strict && UNEXPECTED(Z_DVAL_P(arg) < ZEND_LONG_MIN)) {
1070-
*dest = ZEND_LONG_MIN;
1067+
if (UNEXPECTED(zend_isnan(Z_DVAL_P(arg)))) {
1068+
return 0;
1069+
}
1070+
if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(Z_DVAL_P(arg)))) {
1071+
/* Ironically, the strict parameter makes zpp *non*-strict here */
1072+
if (strict) {
1073+
*dest = (Z_DVAL_P(arg) > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN;
1074+
} else {
1075+
return 0;
1076+
}
10711077
} else {
10721078
*dest = zend_dval_to_lval(Z_DVAL_P(arg));
10731079
}
@@ -1077,10 +1083,15 @@ static zend_always_inline int _z_param_long(zval *arg, zend_long *dest, zend_boo
10771083

10781084
if (UNEXPECTED((type = is_numeric_str_function(Z_STR_P(arg), dest, &d)) != IS_LONG)) {
10791085
if (EXPECTED(type != 0)) {
1080-
if (strict && UNEXPECTED(d > ZEND_LONG_MAX)) {
1081-
*dest = ZEND_LONG_MAX;
1082-
} else if (strict && UNEXPECTED(d < ZEND_LONG_MIN)) {
1083-
*dest = ZEND_LONG_MIN;
1086+
if (UNEXPECTED(zend_isnan(d))) {
1087+
return 0;
1088+
}
1089+
if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(d))) {
1090+
if (strict) {
1091+
*dest = (d > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN;
1092+
} else {
1093+
return 0;
1094+
}
10841095
} else {
10851096
*dest = zend_dval_to_lval(d);
10861097
}

Zend/zend_operators.h

+9-3
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,13 @@ ZEND_API zend_uchar _is_numeric_string_ex(const char *str, size_t length, zend_l
8989

9090
END_EXTERN_C()
9191

92+
#if SIZEOF_ZEND_LONG == 4
93+
# define ZEND_DOUBLE_FITS_LONG(d) (!((d) > ZEND_LONG_MAX || (d) < ZEND_LONG_MIN))
94+
#else
95+
/* >= as (double)ZEND_LONG_MAX is outside signed range */
96+
# define ZEND_DOUBLE_FITS_LONG(d) (!((d) >= ZEND_LONG_MAX || (d) < ZEND_LONG_MIN))
97+
#endif
98+
9299
#if ZEND_DVAL_TO_LVAL_CAST_OK
93100
static zend_always_inline zend_long zend_dval_to_lval(double d)
94101
{
@@ -103,7 +110,7 @@ static zend_always_inline zend_long zend_dval_to_lval(double d)
103110
{
104111
if (UNEXPECTED(!zend_finite(d)) || UNEXPECTED(zend_isnan(d))) {
105112
return 0;
106-
} else if (d > ZEND_LONG_MAX || d < ZEND_LONG_MIN) {
113+
} else if (!ZEND_DOUBLE_FITS_LONG(d)) {
107114
double two_pow_32 = pow(2., 32.),
108115
dmod;
109116

@@ -122,8 +129,7 @@ static zend_always_inline zend_long zend_dval_to_lval(double d)
122129
{
123130
if (UNEXPECTED(!zend_finite(d)) || UNEXPECTED(zend_isnan(d))) {
124131
return 0;
125-
/* >= as (double)ZEND_LONG_MAX is outside signed range */
126-
} else if (d >= ZEND_LONG_MAX || d < ZEND_LONG_MIN) {
132+
} else if (!ZEND_DOUBLE_FITS_LONG(d)) {
127133
double two_pow_64 = pow(2., 64.),
128134
dmod;
129135

ext/date/tests/bug36988.phpt

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
--TEST--
22
Bug #36988 (mktime freezes on long numbers)
3+
--SKIPIF--
4+
<?php if (PHP_INT_SIZE != 4) echo "skip this test is for 32-bit only"; ?>
35
--FILE--
46
<?php
57
date_default_timezone_set('GMT');
68
$start = microtime(true);
79
$a = mktime(1, 1, 1, 1, 1, 11111111111);
8-
echo (microtime(true) - $start) < 1 ? "smaller than one second" : "more than a second";
910
?>
10-
--EXPECT--
11-
smaller than one second
11+
--EXPECTF--
12+
Warning: mktime() expects parameter 6 to be long, double given in %s on line %d

ext/date/tests/bug52062.phpt

+7-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Bug #52062 (large timestamps with DateTime::getTimestamp and DateTime::setTimestamp) (32 bit)
33
--SKIPIF--
44
<?php
5-
if (PHP_INT_SIZE == 8) die('skip 32-bit only');
5+
if (PHP_INT_SIZE != 4) die('skip 32-bit only');
66
?>
77
--INI--
88
date.timezone=UTC
@@ -20,10 +20,12 @@ var_dump($d->getTimestamp());
2020
$i = new DateInterval('PT100000000000S');
2121
var_dump($i->format('%s'));
2222
?>
23-
--EXPECT--
23+
--EXPECTF--
2424
string(32) "5138-11-16 09:46:40 100000000000"
2525
bool(false)
2626
string(12) "100000000000"
27-
string(30) "2008-07-11 04:56:32 1215752192"
28-
int(1215752192)
29-
string(10) "1215752192"
27+
28+
Warning: DateTime::setTimestamp() expects parameter 1 to be long, double given in %s on line %d
29+
string(32) "5138-11-16 09:46:40 100000000000"
30+
bool(false)
31+
string(10) "1215752192"

ext/date/tests/date_sunrise_variation2.phpt

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
--TEST--
22
Test date_sunrise() function : usage variation - Passing unexpected values to second argument format.
3+
--SKIPIF--
4+
<?php if (PHP_INT_SIZE != 4) echo "skip this test is for 32-bit only"; ?>
35
--FILE--
46
<?php
57
/* Prototype : mixed date_sunrise(mixed time [, int format [, float latitude [, float longitude [, float zenith [, float gmt_offset]]]]])
@@ -114,12 +116,12 @@ bool(false)
114116

115117
--float 12.3456789000e10--
116118

117-
Warning: date_sunrise(): Wrong return format given, pick one of SUNFUNCS_RET_TIMESTAMP, SUNFUNCS_RET_STRING or SUNFUNCS_RET_DOUBLE in %s on line %d
119+
Warning: date_sunrise() expects parameter 2 to be long, double given in %s on line %d
118120
bool(false)
119121

120122
--float -12.3456789000e10--
121123

122-
Warning: date_sunrise(): Wrong return format given, pick one of SUNFUNCS_RET_TIMESTAMP, SUNFUNCS_RET_STRING or SUNFUNCS_RET_DOUBLE in %s on line %d
124+
Warning: date_sunrise() expects parameter 2 to be long, double given in %s on line %d
123125
bool(false)
124126

125127
--float .5--

ext/date/tests/date_sunrise_variation9.phpt

+27-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
--TEST--
22
Test date_sunrise() function : usage variation - Passing high positive and negative float values to time argument.
3+
--SKIPIF--
4+
<?php if (PHP_INT_SIZE != 4) echo "skip this test is for 32-bit only"; ?>
35
--FILE--
46
<?php
57
/* Prototype : mixed date_sunrise(mixed time [, int format [, float latitude [, float longitude [, float zenith [, float gmt_offset]]]]])
@@ -32,16 +34,28 @@ var_dump( date_sunrise($time, SUNFUNCS_RET_TIMESTAMP, $latitude, $longitude, $ze
3234

3335
?>
3436
===DONE===
35-
--EXPECTREGEX--
36-
\*\*\* Testing date_sunrise\(\) : usage variation \*\*\*
37-
38-
-- Testing date_sunrise\(\) function by passing float 12.3456789000e10 value to time --
39-
string\(5\) "(07:34|07:49)"
40-
float\((7.566[0-9]*|7.821[0-9]*)\)
41-
int\((-1097256359|123456811756)\)
42-
43-
-- Testing date_sunrise\(\) function by passing float -12.3456789000e10 value to time --
44-
string\(5\) "(07:42|08:48|08:04)"
45-
float\((7.713[0-9]*|8.810[0-9]*|8.074[0-9]*)\)
46-
int\((1097304168|-2147443882|-123456761731)\)
47-
===DONE===
37+
--EXPECTF--
38+
*** Testing date_sunrise() : usage variation ***
39+
40+
-- Testing date_sunrise() function by passing float 12.3456789000e10 value to time --
41+
42+
Warning: date_sunrise() expects parameter 1 to be long, double given in %s on line %d
43+
bool(false)
44+
45+
Warning: date_sunrise() expects parameter 1 to be long, double given in %s on line %d
46+
bool(false)
47+
48+
Warning: date_sunrise() expects parameter 1 to be long, double given in %s on line %d
49+
bool(false)
50+
51+
-- Testing date_sunrise() function by passing float -12.3456789000e10 value to time --
52+
53+
Warning: date_sunrise() expects parameter 1 to be long, double given in %s on line %d
54+
bool(false)
55+
56+
Warning: date_sunrise() expects parameter 1 to be long, double given in %s on line %d
57+
bool(false)
58+
59+
Warning: date_sunrise() expects parameter 1 to be long, double given in %s on line %d
60+
bool(false)
61+
===DONE===

ext/date/tests/date_sunset_variation2.phpt

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
--TEST--
22
Test date_sunset() function : usage variation - Passing unexpected values to second argument format.
3+
--SKIPIF--
4+
<?php if (PHP_INT_SIZE != 4) echo "skip this test is for 32-bit only"; ?>
35
--FILE--
46
<?php
57
/* Prototype : mixed date_sunset(mixed time [, int format [, float latitude [, float longitude [, float zenith [, float gmt_offset]]]]])
@@ -114,12 +116,12 @@ bool(false)
114116

115117
--float 12.3456789000e10--
116118

117-
Warning: date_sunset(): Wrong return format given, pick one of SUNFUNCS_RET_TIMESTAMP, SUNFUNCS_RET_STRING or SUNFUNCS_RET_DOUBLE in %s on line %d
119+
Warning: date_sunset() expects parameter 2 to be long, double given in %s on line %d
118120
bool(false)
119121

120122
--float -12.3456789000e10--
121123

122-
Warning: date_sunset(): Wrong return format given, pick one of SUNFUNCS_RET_TIMESTAMP, SUNFUNCS_RET_STRING or SUNFUNCS_RET_DOUBLE in %s on line %d
124+
Warning: date_sunset() expects parameter 2 to be long, double given in %s on line %d
123125
bool(false)
124126

125127
--float .5--
@@ -208,4 +210,4 @@ int(1218199253)
208210

209211
--unset var--
210212
int(1218199253)
211-
===DONE===
213+
===DONE===

ext/date/tests/date_sunset_variation9.phpt

+26-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
--TEST--
22
Test date_sunset() function : usage variation - Passing high positive and negative float values to time argument.
3+
--SKIPIF--
4+
<?php if (PHP_INT_SIZE != 4) echo "skip this test is for 32-bit only"; ?>
35
--FILE--
46
<?php
57
/* Prototype : mixed date_sunset(mixed time [, int format [, float latitude [, float longitude [, float zenith [, float gmt_offset]]]]])
@@ -32,16 +34,28 @@ var_dump( date_sunset($time, SUNFUNCS_RET_TIMESTAMP, $latitude, $longitude, $zen
3234

3335
?>
3436
===DONE===
35-
--EXPECTREGEX--
36-
\*\*\* Testing date_sunset\(\) : usage variation \*\*\*
37-
38-
-- Testing date_sunset\(\) function by passing float 12.3456789000e10 value to time --
39-
string\(5\) "(19:49|19:28)"
40-
float\((19.830[0-9]*|19.830[0-9]*|19.480[0-9]*)\)
41-
int\((-1097212211|123456853728)\)
42-
43-
-- Testing date_sunset\(\) function by passing float -12.3456789000e10 value to time --
44-
string\(5\) "(19:03|18:12|18:48)"
45-
float\((19.056[0-9]*|18.213[0-9]*|18.808[0-9]*)\)
46-
int\((1097345002|-2147410031|-123456723090)\)
37+
--EXPECTF--
38+
*** Testing date_sunset() : usage variation ***
39+
40+
-- Testing date_sunset() function by passing float 12.3456789000e10 value to time --
41+
42+
Warning: date_sunset() expects parameter 1 to be long, double given in %s on line %d
43+
bool(false)
44+
45+
Warning: date_sunset() expects parameter 1 to be long, double given in %s on line %d
46+
bool(false)
47+
48+
Warning: date_sunset() expects parameter 1 to be long, double given in %s on line %d
49+
bool(false)
50+
51+
-- Testing date_sunset() function by passing float -12.3456789000e10 value to time --
52+
53+
Warning: date_sunset() expects parameter 1 to be long, double given in %s on line %d
54+
bool(false)
55+
56+
Warning: date_sunset() expects parameter 1 to be long, double given in %s on line %d
57+
bool(false)
58+
59+
Warning: date_sunset() expects parameter 1 to be long, double given in %s on line %d
60+
bool(false)
4761
===DONE===
+12-53
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
--TEST--
22
Test getdate() function : usage variation - Passing high positive and negative float values to timestamp.
3+
--SKIPIF--
4+
<?php if (PHP_INT_SIZE != 4) echo "skip this test is for 32-bit only"; ?>
35
--FILE--
46
<?php
57
/* Prototype : array getdate([int timestamp])
@@ -20,59 +22,16 @@ $timestamp = -12.3456789000e10;
2022
var_dump( getdate($timestamp) );
2123
?>
2224
===DONE===
23-
--EXPECTREGEX--
25+
--EXPECTF--
26+
*** Testing getdate() : usage variation ***
2427

25-
\*\*\* Testing getdate\(\) : usage variation \*\*\*
28+
-- Testing getdate() function by passing float 12.3456789000e10 value to timestamp --
2629

27-
-- Testing getdate\(\) function by passing float 12.3456789000e10 value to timestamp --
28-
array\(11\) {
29-
\["seconds"\]=>
30-
int\((36|0)\)
31-
\["minutes"\]=>
32-
int\((43|0)\)
33-
\["hours"\]=>
34-
int\((10|6)\)
35-
\["mday"\]=>
36-
int\((26|11)\)
37-
\["wday"\]=>
38-
int\((2|6)\)
39-
\["mon"\]=>
40-
int\(3\)
41-
\["year"\]=>
42-
int\((1935|5882)\)
43-
\["yday"\]=>
44-
int\((84|69)\)
45-
\["weekday"\]=>
46-
string\((7|8)\) "(Tuesday|Saturday)"
47-
\["month"\]=>
48-
string\(5\) "March"
49-
\[0\]=>
50-
int\((-1097262584|123456789000)\)
51-
}
30+
Warning: getdate() expects parameter 1 to be long, double given in %s on line %d
31+
bool(false)
5232

53-
-- Testing getdate\(\) function by passing float -12.3456789000e10 value to timestamp --
54-
array\(11\) {
55-
\["seconds"\]=>
56-
int\((44|12|20)\)
57-
\["minutes"\]=>
58-
int\((39|23)\)
59-
\["hours"\]=>
60-
int\((0|2|5)\)
61-
\["mday"\]=>
62-
int\((9|14|23)\)
63-
\["wday"\]=>
64-
int\(0\)
65-
\["mon"\]=>
66-
int\((10|12)\)
67-
\["year"\]=>
68-
int\((2004|1901|-1943)\)
69-
\["yday"\]=>
70-
int\((282|347|295)\)
71-
\["weekday"\]=>
72-
string\(6\) "Sunday"
73-
\["month"\]=>
74-
string\((7|8)\) "(October|December)"
75-
\[0\]=>
76-
int\((1097262584|-2147483648|-123456789000)\)
77-
}
78-
===DONE===
33+
-- Testing getdate() function by passing float -12.3456789000e10 value to timestamp --
34+
35+
Warning: getdate() expects parameter 1 to be long, double given in %s on line %d
36+
bool(false)
37+
===DONE===

0 commit comments

Comments
 (0)