From fbb156d88adee83e6f52fec5e3b106e0132dcd46 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Fri, 24 Nov 2023 23:48:48 +0100 Subject: [PATCH 1/5] Fixed int32 underflow on DateTime::createFromTimestamp --- ext/date/php_date.c | 10 +- ext/date/tests/createFromTimestamp.phpt | 60 +-------- ext/date/tests/createFromTimestamp_32bit.phpt | 127 ++++++++++++++++++ 3 files changed, 132 insertions(+), 65 deletions(-) create mode 100644 ext/date/tests/createFromTimestamp_32bit.phpt diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 02236d6676ea7..1c832422a8ffc 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -2522,12 +2522,13 @@ PHPAPI void php_date_initialize_from_ts_long(php_date_obj *dateobj, zend_long se PHPAPI bool php_date_initialize_from_ts_double(php_date_obj *dateobj, double ts) /* {{{ */ { double sec_dval = trunc(ts); - zend_long sec; - int usec; + zend_long sec = (zend_long)sec_dval; + int usec = (int)(fmod(ts, 1) * 1000000); if (UNEXPECTED(isnan(sec_dval) - || sec_dval >= (double)TIMELIB_LONG_MAX + || sec_dval > (double)TIMELIB_LONG_MAX || sec_dval < (double)TIMELIB_LONG_MIN + || (sec == TIMELIB_LONG_MIN && usec < 0) )) { zend_throw_error( date_ce_date_range_error, @@ -2539,9 +2540,6 @@ PHPAPI bool php_date_initialize_from_ts_double(php_date_obj *dateobj, double ts) return false; } - sec = (zend_long)sec_dval; - usec = (int)(fmod(ts, 1) * 1000000); - if (UNEXPECTED(usec < 0)) { sec = sec - 1; usec = 1000000 + usec; diff --git a/ext/date/tests/createFromTimestamp.phpt b/ext/date/tests/createFromTimestamp.phpt index 492a831731e12..723663646712a 100644 --- a/ext/date/tests/createFromTimestamp.phpt +++ b/ext/date/tests/createFromTimestamp.phpt @@ -1,9 +1,5 @@ --TEST-- Tests for DateTime[Immutable]::createFromTimestamp ---SKIPIF-- - --INI-- date.timezone=Europe/London --FILE-- @@ -12,10 +8,6 @@ date.timezone=Europe/London class MyDateTime extends DateTime {}; class MyDateTimeImmutable extends DateTimeImmutable {}; -define('MAX_32BIT', 2147483647); -// -2147483648 may not be expressed in a literal due to parsing peculiarities. -define('MIN_32BIT', -2147483647 - 1); - $timestamps = array( 1696883232, -1696883232, @@ -26,9 +18,6 @@ $timestamps = array( 0, 0.0, -0.0, - MAX_32BIT, - MIN_32BIT, - MIN_32BIT - 0.5, PHP_INT_MAX + 1024.0, PHP_INT_MIN - 1025.0, NAN, @@ -212,54 +201,6 @@ DateTimeImmutable::createFromTimestamp(-0.0): object(DateTimeImmutable)#%d (3) { ["timezone"]=> string(6) "+00:00" } -DateTime::createFromTimestamp(2147483647): object(DateTime)#%d (3) { - ["date"]=> - string(26) "2038-01-19 03:14:07.000000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} -DateTimeImmutable::createFromTimestamp(2147483647): object(DateTimeImmutable)#%d (3) { - ["date"]=> - string(26) "2038-01-19 03:14:07.000000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} -DateTime::createFromTimestamp(-2147483648): object(DateTime)#%d (3) { - ["date"]=> - string(26) "1901-12-13 20:45:52.000000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} -DateTimeImmutable::createFromTimestamp(-2147483648): object(DateTimeImmutable)#%d (3) { - ["date"]=> - string(26) "1901-12-13 20:45:52.000000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} -DateTime::createFromTimestamp(-2147483648.5): object(DateTime)#%d (3) { - ["date"]=> - string(26) "1901-12-13 20:45:51.500000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} -DateTimeImmutable::createFromTimestamp(-2147483648.5): object(DateTimeImmutable)#%d (3) { - ["date"]=> - string(26) "1901-12-13 20:45:51.500000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} DateTime::createFromTimestamp(%f): DateRangeError: Seconds must be a finite number between %i and %i, %f given DateTimeImmutable::createFromTimestamp(%f): DateRangeError: Seconds must be a finite number between %i and %i, %f given DateTime::createFromTimestamp(%f): DateRangeError: Seconds must be a finite number between %i and %i, %f given @@ -286,3 +227,4 @@ MyDateTimeImmutable::createFromTimestamp(0): object(MyDateTimeImmutable)#%d (3) ["timezone"]=> string(6) "+00:00" } + diff --git a/ext/date/tests/createFromTimestamp_32bit.phpt b/ext/date/tests/createFromTimestamp_32bit.phpt new file mode 100644 index 0000000000000..55cc30d15bc3b --- /dev/null +++ b/ext/date/tests/createFromTimestamp_32bit.phpt @@ -0,0 +1,127 @@ +--TEST-- +Tests for DateTime[Immutable]::createFromTimestamp 32bit variant +--SKIPIF-- + +--INI-- +date.timezone=Europe/London +--FILE-- +getMessage() . "\n"; + } + + echo 'DateTimeImmutable::createFromTimestamp(' . var_export($ts, true) . '): '; + try { + var_dump(DateTimeImmutable::createFromTimestamp($ts)); + } catch (Throwable $e) { + echo get_class($e) . ': ' . $e->getMessage() . "\n"; + } +} + +?> +--EXPECTF-- +DateTime::createFromTimestamp(2147483647): object(DateTime)#%d (3) { + ["date"]=> + string(26) "2038-01-19 03:14:07.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTimeImmutable::createFromTimestamp(2147483647): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "2038-01-19 03:14:07.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTime::createFromTimestamp(-2147483647-1): object(DateTime)#%d (3) { + ["date"]=> + string(26) "1901-12-13 20:45:52.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTimeImmutable::createFromTimestamp(-2147483647-1): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "1901-12-13 20:45:52.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTime::createFromTimestamp(2147483647.5): object(DateTime)#%d (3) { + ["date"]=> + string(26) "2038-01-19 03:14:07.500000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTimeImmutable::createFromTimestamp(2147483647.5): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "2038-01-19 03:14:07.500000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTime::createFromTimestamp(-2147483647.5): object(DateTime)#%d (3) { + ["date"]=> + string(26) "1901-12-13 20:45:52.500000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTimeImmutable::createFromTimestamp(-2147483647.5): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "1901-12-13 20:45:52.500000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTime::createFromTimestamp(2147483646.5): object(DateTime)#%d (3) { + ["date"]=> + string(26) "2038-01-19 03:14:06.500000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTimeImmutable::createFromTimestamp(2147483646.5): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "2038-01-19 03:14:06.500000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTime::createFromTimestamp(-2147483648.5): DateRangeError: Seconds must be a finite number between -2147483648 and 2147483647, -2.14748e+9 given +DateTimeImmutable::createFromTimestamp(-2147483648.5): DateRangeError: Seconds must be a finite number between -2147483648 and 2147483647, -2.14748e+9 given +DateTime::createFromTimestamp(2147484671.0): DateRangeError: Seconds must be a finite number between -2147483648 and 2147483647, 2.14748e+9 given +DateTimeImmutable::createFromTimestamp(2147484671.0): DateRangeError: Seconds must be a finite number between -2147483648 and 2147483647, 2.14748e+9 given +DateTime::createFromTimestamp(-2147484673.0): DateRangeError: Seconds must be a finite number between -2147483648 and 2147483647, -2.14748e+9 given +DateTimeImmutable::createFromTimestamp(-2147484673.0): DateRangeError: Seconds must be a finite number between -2147483648 and 2147483647, -2.14748e+9 given + From 26d3153c33b079e1cb5bd48c560dce2c9d322d64 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Sat, 25 Nov 2023 00:45:37 +0100 Subject: [PATCH 2/5] Added PHP_DATE_SIZEOF_LONG/PHP_DATE_DOUBLE_FITS_LONG similar to SIZEOF_ZEND_LONG/ZEND_DOUBLE_FITS_LONG --- ext/date/php_date.c | 26 ++++++++++++++++++-------- ext/date/php_date.h | 17 +++++++++++++++++ 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 1c832422a8ffc..62ffbbbd72343 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -2522,14 +2522,10 @@ PHPAPI void php_date_initialize_from_ts_long(php_date_obj *dateobj, zend_long se PHPAPI bool php_date_initialize_from_ts_double(php_date_obj *dateobj, double ts) /* {{{ */ { double sec_dval = trunc(ts); - zend_long sec = (zend_long)sec_dval; - int usec = (int)(fmod(ts, 1) * 1000000); - - if (UNEXPECTED(isnan(sec_dval) - || sec_dval > (double)TIMELIB_LONG_MAX - || sec_dval < (double)TIMELIB_LONG_MIN - || (sec == TIMELIB_LONG_MIN && usec < 0) - )) { + zend_long sec; + int usec; + + if (UNEXPECTED(isnan(sec_dval) || !PHP_DATE_DOUBLE_FITS_LONG(sec_dval))) { zend_throw_error( date_ce_date_range_error, "Seconds must be a finite number between " TIMELIB_LONG_FMT " and " TIMELIB_LONG_FMT ", %g given", @@ -2540,7 +2536,21 @@ PHPAPI bool php_date_initialize_from_ts_double(php_date_obj *dateobj, double ts) return false; } + sec = (zend_long)sec_dval; + usec = (int)(fmod(ts, 1) * 1000000); + if (UNEXPECTED(usec < 0)) { + if (UNEXPECTED(sec == TIMELIB_LONG_MIN)) { + zend_throw_error( + date_ce_date_range_error, + "Seconds must be a finite number between " TIMELIB_LONG_FMT " and " TIMELIB_LONG_FMT ", %g given", + TIMELIB_LONG_MIN, + TIMELIB_LONG_MAX, + sec_dval + ); + return false; + } + sec = sec - 1; usec = 1000000 + usec; } diff --git a/ext/date/php_date.h b/ext/date/php_date.h index 97f4bcc0a843f..a2e0eab356213 100644 --- a/ext/date/php_date.h +++ b/ext/date/php_date.h @@ -20,6 +20,23 @@ #include "lib/timelib.h" #include "Zend/zend_hash.h" +/* Same as SIZEOF_ZEND_LONG but using TIMELIB_LONG_MAX/MIN */ +#if TIMELIB_LONG_MAX == 2147483647 +# define PHP_DATE_SIZEOF_LONG 4 +#elif TIMELIB_LONG_MAX == 9223372036854775807 +# define PHP_DATE_SIZEOF_LONG 8 +#else +# error "Unknown TIMELIB LONG SIZE" +#endif + +/* Same as ZEND_DOUBLE_FITS_LONG but using TIMELIB_LONG_MAX/MIN */ +#if PHP_DATE_SIZEOF_LONG == 4 +# define PHP_DATE_DOUBLE_FITS_LONG(d) (!((d) > (double)TIMELIB_LONG_MAX || (d) < (double)TIMELIB_LONG_MIN)) +#elif PHP_DATE_SIZEOF_LONG == 8 + /* >= as (double)TIMELIB_LONG_MAX is outside signed range */ +# define PHP_DATE_DOUBLE_FITS_LONG(d) (!((d) >= (double)TIMELIB_LONG_MAX || (d) < (double)TIMELIB_LONG_MIN)) +#endif + #include "php_version.h" #define PHP_DATE_VERSION PHP_VERSION From 075f0bd3cb44b89a0c908ddeb2dc5fd38bdc5e38 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Wed, 20 Dec 2023 14:07:47 +0100 Subject: [PATCH 3/5] Addressed PR comments --- ext/date/php_date.h | 16 ++++++++-------- ext/date/tests/createFromTimestamp.phpt | 1 - ext/date/tests/createFromTimestamp_32bit.phpt | 1 - 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/ext/date/php_date.h b/ext/date/php_date.h index a2e0eab356213..f1b7c892001a9 100644 --- a/ext/date/php_date.h +++ b/ext/date/php_date.h @@ -21,20 +21,20 @@ #include "Zend/zend_hash.h" /* Same as SIZEOF_ZEND_LONG but using TIMELIB_LONG_MAX/MIN */ -#if TIMELIB_LONG_MAX == 2147483647 -# define PHP_DATE_SIZEOF_LONG 4 -#elif TIMELIB_LONG_MAX == 9223372036854775807 -# define PHP_DATE_SIZEOF_LONG 8 +#if TIMELIB_LONG_MAX == INT32_MAX +# define PHP_DATE_SIZEOF_LONG 4 +#elif TIMELIB_LONG_MAX == INT64_MAX +# define PHP_DATE_SIZEOF_LONG 8 #else -# error "Unknown TIMELIB LONG SIZE" +# error "Unknown TIMELIB LONG SIZE" #endif /* Same as ZEND_DOUBLE_FITS_LONG but using TIMELIB_LONG_MAX/MIN */ #if PHP_DATE_SIZEOF_LONG == 4 -# define PHP_DATE_DOUBLE_FITS_LONG(d) (!((d) > (double)TIMELIB_LONG_MAX || (d) < (double)TIMELIB_LONG_MIN)) +# define PHP_DATE_DOUBLE_FITS_LONG(d) (!((d) > (double)TIMELIB_LONG_MAX || (d) < (double)TIMELIB_LONG_MIN)) #elif PHP_DATE_SIZEOF_LONG == 8 - /* >= as (double)TIMELIB_LONG_MAX is outside signed range */ -# define PHP_DATE_DOUBLE_FITS_LONG(d) (!((d) >= (double)TIMELIB_LONG_MAX || (d) < (double)TIMELIB_LONG_MIN)) + /* >= as (double)TIMELIB_LONG_MAX is outside signed range */ +# define PHP_DATE_DOUBLE_FITS_LONG(d) (!((d) >= (double)TIMELIB_LONG_MAX || (d) < (double)TIMELIB_LONG_MIN)) #endif #include "php_version.h" diff --git a/ext/date/tests/createFromTimestamp.phpt b/ext/date/tests/createFromTimestamp.phpt index 723663646712a..daa0fe39b3392 100644 --- a/ext/date/tests/createFromTimestamp.phpt +++ b/ext/date/tests/createFromTimestamp.phpt @@ -227,4 +227,3 @@ MyDateTimeImmutable::createFromTimestamp(0): object(MyDateTimeImmutable)#%d (3) ["timezone"]=> string(6) "+00:00" } - diff --git a/ext/date/tests/createFromTimestamp_32bit.phpt b/ext/date/tests/createFromTimestamp_32bit.phpt index 55cc30d15bc3b..b8c327826153c 100644 --- a/ext/date/tests/createFromTimestamp_32bit.phpt +++ b/ext/date/tests/createFromTimestamp_32bit.phpt @@ -124,4 +124,3 @@ DateTime::createFromTimestamp(2147484671.0): DateRangeError: Seconds must be a f DateTimeImmutable::createFromTimestamp(2147484671.0): DateRangeError: Seconds must be a finite number between -2147483648 and 2147483647, 2.14748e+9 given DateTime::createFromTimestamp(-2147484673.0): DateRangeError: Seconds must be a finite number between -2147483648 and 2147483647, -2.14748e+9 given DateTimeImmutable::createFromTimestamp(-2147484673.0): DateRangeError: Seconds must be a finite number between -2147483648 and 2147483647, -2.14748e+9 given - From 42c6b1a0de76c8ad8bbf2cb3ac33899f759aedc7 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Wed, 20 Dec 2023 14:18:53 +0100 Subject: [PATCH 4/5] Improve date range error message --- ext/date/php_date.c | 10 +++++----- ext/date/tests/createFromTimestamp.phpt | 20 +++++++++---------- ext/date/tests/createFromTimestamp_32bit.phpt | 12 +++++------ 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 62ffbbbd72343..da50b54c2bcff 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -2528,10 +2528,10 @@ PHPAPI bool php_date_initialize_from_ts_double(php_date_obj *dateobj, double ts) if (UNEXPECTED(isnan(sec_dval) || !PHP_DATE_DOUBLE_FITS_LONG(sec_dval))) { zend_throw_error( date_ce_date_range_error, - "Seconds must be a finite number between " TIMELIB_LONG_FMT " and " TIMELIB_LONG_FMT ", %g given", + "Timestamp must be a finite number between " TIMELIB_LONG_FMT " and " TIMELIB_LONG_FMT ".999999, %g given", TIMELIB_LONG_MIN, TIMELIB_LONG_MAX, - sec_dval + ts ); return false; } @@ -2543,14 +2543,14 @@ PHPAPI bool php_date_initialize_from_ts_double(php_date_obj *dateobj, double ts) if (UNEXPECTED(sec == TIMELIB_LONG_MIN)) { zend_throw_error( date_ce_date_range_error, - "Seconds must be a finite number between " TIMELIB_LONG_FMT " and " TIMELIB_LONG_FMT ", %g given", + "Timestamp must be a finite number between " TIMELIB_LONG_FMT " and " TIMELIB_LONG_FMT ".999999, %g given", TIMELIB_LONG_MIN, TIMELIB_LONG_MAX, - sec_dval + ts ); return false; } - + sec = sec - 1; usec = 1000000 + usec; } diff --git a/ext/date/tests/createFromTimestamp.phpt b/ext/date/tests/createFromTimestamp.phpt index daa0fe39b3392..9dd99389a281f 100644 --- a/ext/date/tests/createFromTimestamp.phpt +++ b/ext/date/tests/createFromTimestamp.phpt @@ -201,16 +201,16 @@ DateTimeImmutable::createFromTimestamp(-0.0): object(DateTimeImmutable)#%d (3) { ["timezone"]=> string(6) "+00:00" } -DateTime::createFromTimestamp(%f): DateRangeError: Seconds must be a finite number between %i and %i, %f given -DateTimeImmutable::createFromTimestamp(%f): DateRangeError: Seconds must be a finite number between %i and %i, %f given -DateTime::createFromTimestamp(%f): DateRangeError: Seconds must be a finite number between %i and %i, %f given -DateTimeImmutable::createFromTimestamp(%f): DateRangeError: Seconds must be a finite number between %i and %i, %f given -DateTime::createFromTimestamp(NAN): DateRangeError: Seconds must be a finite number between %i and %i, NAN given -DateTimeImmutable::createFromTimestamp(NAN): DateRangeError: Seconds must be a finite number between %i and %i, NAN given -DateTime::createFromTimestamp(INF): DateRangeError: Seconds must be a finite number between %i and %i, INF given -DateTimeImmutable::createFromTimestamp(INF): DateRangeError: Seconds must be a finite number between %i and %i, INF given -DateTime::createFromTimestamp(-INF): DateRangeError: Seconds must be a finite number between %i and %i, -INF given -DateTimeImmutable::createFromTimestamp(-INF): DateRangeError: Seconds must be a finite number between %i and %i, -INF given +DateTime::createFromTimestamp(%f): DateRangeError: Timestamp must be a finite number between %i and %i.999999, %f given +DateTimeImmutable::createFromTimestamp(%f): DateRangeError: Timestamp must be a finite number between %i and %i.999999, %f given +DateTime::createFromTimestamp(%f): DateRangeError: Timestamp must be a finite number between %i and %i.999999, %f given +DateTimeImmutable::createFromTimestamp(%f): DateRangeError: Timestamp must be a finite number between %i and %i.999999, %f given +DateTime::createFromTimestamp(NAN): DateRangeError: Timestamp must be a finite number between %i and %i.999999, NAN given +DateTimeImmutable::createFromTimestamp(NAN): DateRangeError: Timestamp must be a finite number between %i and %i.999999, NAN given +DateTime::createFromTimestamp(INF): DateRangeError: Timestamp must be a finite number between %i and %i.999999, INF given +DateTimeImmutable::createFromTimestamp(INF): DateRangeError: Timestamp must be a finite number between %i and %i.999999, INF given +DateTime::createFromTimestamp(-INF): DateRangeError: Timestamp must be a finite number between %i and %i.999999, -INF given +DateTimeImmutable::createFromTimestamp(-INF): DateRangeError: Timestamp must be a finite number between %i and %i.999999, -INF given MyDateTime::createFromTimestamp(0): object(MyDateTime)#%d (3) { ["date"]=> string(26) "1970-01-01 00:00:00.000000" diff --git a/ext/date/tests/createFromTimestamp_32bit.phpt b/ext/date/tests/createFromTimestamp_32bit.phpt index b8c327826153c..62479ea7de127 100644 --- a/ext/date/tests/createFromTimestamp_32bit.phpt +++ b/ext/date/tests/createFromTimestamp_32bit.phpt @@ -118,9 +118,9 @@ DateTimeImmutable::createFromTimestamp(2147483646.5): object(DateTimeImmutable)# ["timezone"]=> string(6) "+00:00" } -DateTime::createFromTimestamp(-2147483648.5): DateRangeError: Seconds must be a finite number between -2147483648 and 2147483647, -2.14748e+9 given -DateTimeImmutable::createFromTimestamp(-2147483648.5): DateRangeError: Seconds must be a finite number between -2147483648 and 2147483647, -2.14748e+9 given -DateTime::createFromTimestamp(2147484671.0): DateRangeError: Seconds must be a finite number between -2147483648 and 2147483647, 2.14748e+9 given -DateTimeImmutable::createFromTimestamp(2147484671.0): DateRangeError: Seconds must be a finite number between -2147483648 and 2147483647, 2.14748e+9 given -DateTime::createFromTimestamp(-2147484673.0): DateRangeError: Seconds must be a finite number between -2147483648 and 2147483647, -2.14748e+9 given -DateTimeImmutable::createFromTimestamp(-2147484673.0): DateRangeError: Seconds must be a finite number between -2147483648 and 2147483647, -2.14748e+9 given +DateTime::createFromTimestamp(-2147483648.5): DateRangeError: Timestamp must be a finite number between -2147483648 and 2147483647.999999, -2.14748e+9 given +DateTimeImmutable::createFromTimestamp(-2147483648.5): DateRangeError: Timestamp must be a finite number between -2147483648 and 2147483647.999999, -2.14748e+9 given +DateTime::createFromTimestamp(2147484671.0): DateRangeError: Timestamp must be a finite number between -2147483648 and 2147483647.999999, 2.14748e+9 given +DateTimeImmutable::createFromTimestamp(2147484671.0): DateRangeError: Timestamp must be a finite number between -2147483648 and 2147483647.999999, 2.14748e+9 given +DateTime::createFromTimestamp(-2147484673.0): DateRangeError: Timestamp must be a finite number between -2147483648 and 2147483647.999999, -2.14748e+9 given +DateTimeImmutable::createFromTimestamp(-2147484673.0): DateRangeError: Timestamp must be a finite number between -2147483648 and 2147483647.999999, -2.14748e+9 given From cbaadb5211947a74adad0bb3ae690db555c88184 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Wed, 20 Dec 2023 22:03:47 +0100 Subject: [PATCH 5/5] Use zend_argument_error --- ext/date/php_date.c | 10 ++++++---- ext/date/tests/createFromTimestamp.phpt | 20 +++++++++---------- ext/date/tests/createFromTimestamp_32bit.phpt | 12 +++++------ 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/ext/date/php_date.c b/ext/date/php_date.c index da50b54c2bcff..ef1b8621c7cf0 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -2526,9 +2526,10 @@ PHPAPI bool php_date_initialize_from_ts_double(php_date_obj *dateobj, double ts) int usec; if (UNEXPECTED(isnan(sec_dval) || !PHP_DATE_DOUBLE_FITS_LONG(sec_dval))) { - zend_throw_error( + zend_argument_error( date_ce_date_range_error, - "Timestamp must be a finite number between " TIMELIB_LONG_FMT " and " TIMELIB_LONG_FMT ".999999, %g given", + 1, + "must be a finite number between " TIMELIB_LONG_FMT " and " TIMELIB_LONG_FMT ".999999, %g given", TIMELIB_LONG_MIN, TIMELIB_LONG_MAX, ts @@ -2541,9 +2542,10 @@ PHPAPI bool php_date_initialize_from_ts_double(php_date_obj *dateobj, double ts) if (UNEXPECTED(usec < 0)) { if (UNEXPECTED(sec == TIMELIB_LONG_MIN)) { - zend_throw_error( + zend_argument_error( date_ce_date_range_error, - "Timestamp must be a finite number between " TIMELIB_LONG_FMT " and " TIMELIB_LONG_FMT ".999999, %g given", + 1, + "must be a finite number between " TIMELIB_LONG_FMT " and " TIMELIB_LONG_FMT ".999999, %g given", TIMELIB_LONG_MIN, TIMELIB_LONG_MAX, ts diff --git a/ext/date/tests/createFromTimestamp.phpt b/ext/date/tests/createFromTimestamp.phpt index 9dd99389a281f..474a55bc6db6d 100644 --- a/ext/date/tests/createFromTimestamp.phpt +++ b/ext/date/tests/createFromTimestamp.phpt @@ -201,16 +201,16 @@ DateTimeImmutable::createFromTimestamp(-0.0): object(DateTimeImmutable)#%d (3) { ["timezone"]=> string(6) "+00:00" } -DateTime::createFromTimestamp(%f): DateRangeError: Timestamp must be a finite number between %i and %i.999999, %f given -DateTimeImmutable::createFromTimestamp(%f): DateRangeError: Timestamp must be a finite number between %i and %i.999999, %f given -DateTime::createFromTimestamp(%f): DateRangeError: Timestamp must be a finite number between %i and %i.999999, %f given -DateTimeImmutable::createFromTimestamp(%f): DateRangeError: Timestamp must be a finite number between %i and %i.999999, %f given -DateTime::createFromTimestamp(NAN): DateRangeError: Timestamp must be a finite number between %i and %i.999999, NAN given -DateTimeImmutable::createFromTimestamp(NAN): DateRangeError: Timestamp must be a finite number between %i and %i.999999, NAN given -DateTime::createFromTimestamp(INF): DateRangeError: Timestamp must be a finite number between %i and %i.999999, INF given -DateTimeImmutable::createFromTimestamp(INF): DateRangeError: Timestamp must be a finite number between %i and %i.999999, INF given -DateTime::createFromTimestamp(-INF): DateRangeError: Timestamp must be a finite number between %i and %i.999999, -INF given -DateTimeImmutable::createFromTimestamp(-INF): DateRangeError: Timestamp must be a finite number between %i and %i.999999, -INF given +DateTime::createFromTimestamp(%f): DateRangeError: DateTime::createFromTimestamp(): Argument #1 ($timestamp) must be a finite number between %i and %i.999999, %f given +DateTimeImmutable::createFromTimestamp(%f): DateRangeError: DateTimeImmutable::createFromTimestamp(): Argument #1 ($timestamp) must be a finite number between %i and %i.999999, %f given +DateTime::createFromTimestamp(%f): DateRangeError: DateTime::createFromTimestamp(): Argument #1 ($timestamp) must be a finite number between %i and %i.999999, %f given +DateTimeImmutable::createFromTimestamp(%f): DateRangeError: DateTimeImmutable::createFromTimestamp(): Argument #1 ($timestamp) must be a finite number between %i and %i.999999, %f given +DateTime::createFromTimestamp(NAN): DateRangeError: DateTime::createFromTimestamp(): Argument #1 ($timestamp) must be a finite number between %i and %i.999999, NAN given +DateTimeImmutable::createFromTimestamp(NAN): DateRangeError: DateTimeImmutable::createFromTimestamp(): Argument #1 ($timestamp) must be a finite number between %i and %i.999999, NAN given +DateTime::createFromTimestamp(INF): DateRangeError: DateTime::createFromTimestamp(): Argument #1 ($timestamp) must be a finite number between %i and %i.999999, INF given +DateTimeImmutable::createFromTimestamp(INF): DateRangeError: DateTimeImmutable::createFromTimestamp(): Argument #1 ($timestamp) must be a finite number between %i and %i.999999, INF given +DateTime::createFromTimestamp(-INF): DateRangeError: DateTime::createFromTimestamp(): Argument #1 ($timestamp) must be a finite number between %i and %i.999999, -INF given +DateTimeImmutable::createFromTimestamp(-INF): DateRangeError: DateTimeImmutable::createFromTimestamp(): Argument #1 ($timestamp) must be a finite number between %i and %i.999999, -INF given MyDateTime::createFromTimestamp(0): object(MyDateTime)#%d (3) { ["date"]=> string(26) "1970-01-01 00:00:00.000000" diff --git a/ext/date/tests/createFromTimestamp_32bit.phpt b/ext/date/tests/createFromTimestamp_32bit.phpt index 62479ea7de127..8052acfca135a 100644 --- a/ext/date/tests/createFromTimestamp_32bit.phpt +++ b/ext/date/tests/createFromTimestamp_32bit.phpt @@ -118,9 +118,9 @@ DateTimeImmutable::createFromTimestamp(2147483646.5): object(DateTimeImmutable)# ["timezone"]=> string(6) "+00:00" } -DateTime::createFromTimestamp(-2147483648.5): DateRangeError: Timestamp must be a finite number between -2147483648 and 2147483647.999999, -2.14748e+9 given -DateTimeImmutable::createFromTimestamp(-2147483648.5): DateRangeError: Timestamp must be a finite number between -2147483648 and 2147483647.999999, -2.14748e+9 given -DateTime::createFromTimestamp(2147484671.0): DateRangeError: Timestamp must be a finite number between -2147483648 and 2147483647.999999, 2.14748e+9 given -DateTimeImmutable::createFromTimestamp(2147484671.0): DateRangeError: Timestamp must be a finite number between -2147483648 and 2147483647.999999, 2.14748e+9 given -DateTime::createFromTimestamp(-2147484673.0): DateRangeError: Timestamp must be a finite number between -2147483648 and 2147483647.999999, -2.14748e+9 given -DateTimeImmutable::createFromTimestamp(-2147484673.0): DateRangeError: Timestamp must be a finite number between -2147483648 and 2147483647.999999, -2.14748e+9 given +DateTime::createFromTimestamp(-2147483648.5): DateRangeError: DateTime::createFromTimestamp(): Argument #1 ($timestamp) must be a finite number between -2147483648 and 2147483647.999999, -2.14748e+9 given +DateTimeImmutable::createFromTimestamp(-2147483648.5): DateRangeError: DateTimeImmutable::createFromTimestamp(): Argument #1 ($timestamp) must be a finite number between -2147483648 and 2147483647.999999, -2.14748e+9 given +DateTime::createFromTimestamp(2147484671.0): DateRangeError: DateTime::createFromTimestamp(): Argument #1 ($timestamp) must be a finite number between -2147483648 and 2147483647.999999, 2.14748e+9 given +DateTimeImmutable::createFromTimestamp(2147484671.0): DateRangeError: DateTimeImmutable::createFromTimestamp(): Argument #1 ($timestamp) must be a finite number between -2147483648 and 2147483647.999999, 2.14748e+9 given +DateTime::createFromTimestamp(-2147484673.0): DateRangeError: DateTime::createFromTimestamp(): Argument #1 ($timestamp) must be a finite number between -2147483648 and 2147483647.999999, -2.14748e+9 given +DateTimeImmutable::createFromTimestamp(-2147484673.0): DateRangeError: DateTimeImmutable::createFromTimestamp(): Argument #1 ($timestamp) must be a finite number between -2147483648 and 2147483647.999999, -2.14748e+9 given