diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 5f7d6166f27..48c82bf7ec6 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -5489,6 +5489,11 @@ static bool php_date_period_initialize_from_hash(php_period_obj *period_obj, Has if (Z_TYPE_P(ht_entry) == IS_OBJECT && instanceof_function(Z_OBJCE_P(ht_entry), date_ce_interface)) { php_date_obj *date_obj; date_obj = Z_PHPDATE_P(ht_entry); + + if (!date_obj->time) { + return 0; + } + if (period_obj->start != NULL) { timelib_time_dtor(period_obj->start); } @@ -5506,6 +5511,11 @@ static bool php_date_period_initialize_from_hash(php_period_obj *period_obj, Has if (Z_TYPE_P(ht_entry) == IS_OBJECT && instanceof_function(Z_OBJCE_P(ht_entry), date_ce_interface)) { php_date_obj *date_obj; date_obj = Z_PHPDATE_P(ht_entry); + + if (!date_obj->time) { + return 0; + } + if (period_obj->end != NULL) { timelib_time_dtor(period_obj->end); } @@ -5522,6 +5532,11 @@ static bool php_date_period_initialize_from_hash(php_period_obj *period_obj, Has if (Z_TYPE_P(ht_entry) == IS_OBJECT && instanceof_function(Z_OBJCE_P(ht_entry), date_ce_interface)) { php_date_obj *date_obj; date_obj = Z_PHPDATE_P(ht_entry); + + if (!date_obj->time) { + return 0; + } + if (period_obj->current != NULL) { timelib_time_dtor(period_obj->current); } @@ -5538,6 +5553,11 @@ static bool php_date_period_initialize_from_hash(php_period_obj *period_obj, Has if (Z_TYPE_P(ht_entry) == IS_OBJECT && Z_OBJCE_P(ht_entry) == date_ce_interval) { php_interval_obj *interval_obj; interval_obj = Z_PHPINTERVAL_P(ht_entry); + + if (!interval_obj->initialized) { + return 0; + } + if (period_obj->interval != NULL) { timelib_rel_time_dtor(period_obj->interval); } diff --git a/ext/date/tests/bug-gh11416.phpt b/ext/date/tests/bug-gh11416.phpt index 086e16ae7f3..546867924cb 100644 --- a/ext/date/tests/bug-gh11416.phpt +++ b/ext/date/tests/bug-gh11416.phpt @@ -5,6 +5,7 @@ date.timezone=UTC --FILE-- newInstanceWithoutConstructor(); try { @@ -20,9 +21,50 @@ try { echo get_class($e), ': ', $e->getMessage(), "\n"; } +$date = (new ReflectionClass(DateTime::class))->newInstanceWithoutConstructor(); +$dateperiod = (new ReflectionClass(DatePeriod::class))->newInstanceWithoutConstructor(); +$dateinterval = (new ReflectionClass(DateInterval::class))->newInstanceWithoutConstructor(); +try { + $dateperiod->__unserialize(['start' => $date]); +} catch (Error $e) { + echo get_class($e), ': ', $e->getMessage(), "\n"; +} + +try { + $dateperiod->__unserialize(['start' => $now, 'end' => $date]); +} catch (Error $e) { + echo get_class($e), ': ', $e->getMessage(), "\n"; +} + +try { + $dateperiod->__unserialize(['start' => $now, 'end' => $now, 'current' => $date]); +} catch (Error $e) { + echo get_class($e), ': ', $e->getMessage(), "\n"; +} + +try { + $dateperiod->__unserialize(['start' => $now, 'end' => $now, 'current' => $now, 'interval' => $dateinterval]); +} catch (Error $e) { + echo get_class($e), ': ', $e->getMessage(), "\n"; +} + +try { + $dateperiod->__unserialize([ + 'start' => $now, 'end' => $now, 'current' => $now, 'interval' => $simpleInterval, + 'recurrences' => 2, 'include_start_date' => true, 'include_end_date' => true, + ]); + echo "DatePeriod::__unserialize: SUCCESS\n"; +} catch (Error $e) { + echo get_class($e), ': ', $e->getMessage(), "\n"; +} echo "OK\n"; ?> --EXPECT-- DateObjectError: Object of type DateTimeInterface has not been correctly initialized by calling parent::__construct() in its constructor DateObjectError: Object of type DateTimeInterface has not been correctly initialized by calling parent::__construct() in its constructor +Error: Invalid serialization data for DatePeriod object +Error: Invalid serialization data for DatePeriod object +Error: Invalid serialization data for DatePeriod object +Error: Invalid serialization data for DatePeriod object +DatePeriod::__unserialize: SUCCESS OK