From 92f8f19d50da32b228e5e292a475961c6f4893cc Mon Sep 17 00:00:00 2001 From: Derick Rethans Date: Thu, 5 May 2022 11:44:13 +0100 Subject: [PATCH] Fixed GH-8471: Segmentation fault when converting immutable and mutable DateTime instances created using reflection --- ext/date/php_date.c | 16 ++++++++--- ext/date/tests/bug-gh8471.phpt | 50 ++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 ext/date/tests/bug-gh8471.phpt diff --git a/ext/date/php_date.c b/ext/date/php_date.c index ac14ed9f50a56..1b8b57006017c 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -2468,8 +2468,10 @@ PHP_METHOD(DateTime, createFromImmutable) Z_PARAM_OBJECT_OF_CLASS(datetimeimmutable_object, date_ce_immutable) ZEND_PARSE_PARAMETERS_END(); - php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_date, return_value); old_obj = Z_PHPDATE_P(datetimeimmutable_object); + DATE_CHECK_INITIALIZED(old_obj->time, DateTimeImmutable); + + php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_date, return_value); new_obj = Z_PHPDATE_P(return_value); new_obj->time = timelib_time_clone(old_obj->time); @@ -2487,8 +2489,10 @@ PHP_METHOD(DateTime, createFromInterface) Z_PARAM_OBJECT_OF_CLASS(datetimeinterface_object, date_ce_interface) ZEND_PARSE_PARAMETERS_END(); - php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_date, return_value); old_obj = Z_PHPDATE_P(datetimeinterface_object); + DATE_CHECK_INITIALIZED(old_obj->time, DateTimeInterface); + + php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_date, return_value); new_obj = Z_PHPDATE_P(return_value); new_obj->time = timelib_time_clone(old_obj->time); @@ -2506,8 +2510,10 @@ PHP_METHOD(DateTimeImmutable, createFromMutable) Z_PARAM_OBJECT_OF_CLASS(datetime_object, date_ce_date) ZEND_PARSE_PARAMETERS_END(); - php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_immutable, return_value); old_obj = Z_PHPDATE_P(datetime_object); + DATE_CHECK_INITIALIZED(old_obj->time, DateTime); + + php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_immutable, return_value); new_obj = Z_PHPDATE_P(return_value); new_obj->time = timelib_time_clone(old_obj->time); @@ -2525,8 +2531,10 @@ PHP_METHOD(DateTimeImmutable, createFromInterface) Z_PARAM_OBJECT_OF_CLASS(datetimeinterface_object, date_ce_interface) ZEND_PARSE_PARAMETERS_END(); - php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_immutable, return_value); old_obj = Z_PHPDATE_P(datetimeinterface_object); + DATE_CHECK_INITIALIZED(old_obj->time, DateTimeInterface); + + php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_immutable, return_value); new_obj = Z_PHPDATE_P(return_value); new_obj->time = timelib_time_clone(old_obj->time); diff --git a/ext/date/tests/bug-gh8471.phpt b/ext/date/tests/bug-gh8471.phpt new file mode 100644 index 0000000000000..6857551008e08 --- /dev/null +++ b/ext/date/tests/bug-gh8471.phpt @@ -0,0 +1,50 @@ +--TEST-- +Bug GH-8471: Segmentation fault when converting immutable and mutable DateTime instances created using reflection +--FILE-- +newInstanceWithoutConstructor(); +try { + $immutable = \DateTimeImmutable::createFromMutable($mutable); +} catch (Throwable $t) { + echo $t->getMessage(), "\n"; +} + + +$reflection = new ReflectionClass('\DateTime'); + +$mutable = $reflection->newInstanceWithoutConstructor(); +try { + $immutable = \DateTimeImmutable::createFromInterface($mutable); +} catch (Throwable $t) { + echo $t->getMessage(), "\n"; +} + + +$reflection = new ReflectionClass('\DateTimeImmutable'); + +$immutable = $reflection->newInstanceWithoutConstructor(); +try { + $mutable = \DateTime::createFromImmutable($immutable); +} catch (Throwable $t) { + echo $t->getMessage(), "\n"; +} + + +$reflection = new ReflectionClass('\DateTimeImmutable'); + +$immutable = $reflection->newInstanceWithoutConstructor(); +try { + $mutable = \DateTime::createFromInterface($immutable); +} catch (Throwable $t) { + echo $t->getMessage(), "\n"; +} + + +?> +--EXPECTF-- +The DateTime object has not been correctly initialized by its constructor +The DateTimeInterface object has not been correctly initialized by its constructor +The DateTimeImmutable object has not been correctly initialized by its constructor +The DateTimeInterface object has not been correctly initialized by its constructor