mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4: Fix crashes when trying to instantiate uninstantiable classes via date static constructors
This commit is contained in:
@@ -1486,7 +1486,8 @@ static void create_date_period_datetime(timelib_time *datetime, zend_class_entry
|
||||
if (datetime) {
|
||||
php_date_obj *date_obj;
|
||||
|
||||
object_init_ex(zv, ce);
|
||||
zend_result result = object_init_ex(zv, ce);
|
||||
ZEND_ASSERT(result == SUCCESS && "should succeed as it reuses an existing object's ce");
|
||||
date_obj = Z_PHPDATE_P(zv);
|
||||
date_obj->time = timelib_time_clone(datetime);
|
||||
} else {
|
||||
@@ -2318,6 +2319,7 @@ static void add_common_properties(HashTable *myht, zend_object *zobj)
|
||||
}
|
||||
|
||||
/* Advanced Interface */
|
||||
/* TODO: remove this API because it is unsafe to use as-is, as it does not propagate the failure/success status. */
|
||||
PHPAPI zval *php_date_instantiate(zend_class_entry *pce, zval *object) /* {{{ */
|
||||
{
|
||||
object_init_ex(object, pce);
|
||||
@@ -2595,7 +2597,9 @@ PHP_FUNCTION(date_create_from_format)
|
||||
Z_PARAM_OBJECT_OF_CLASS_OR_NULL(timezone_object, date_ce_timezone)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_date, return_value);
|
||||
if (object_init_ex(return_value, execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_date) != SUCCESS) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
if (!php_date_initialize(Z_PHPDATE_P(return_value), time_str, time_str_len, format_str, timezone_object, PHP_DATE_INIT_FORMAT)) {
|
||||
zval_ptr_dtor(return_value);
|
||||
RETURN_FALSE;
|
||||
@@ -2617,7 +2621,9 @@ PHP_FUNCTION(date_create_immutable_from_format)
|
||||
Z_PARAM_OBJECT_OF_CLASS_OR_NULL(timezone_object, date_ce_timezone)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_immutable, return_value);
|
||||
if (object_init_ex(return_value, execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_immutable) != SUCCESS) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
if (!php_date_initialize(Z_PHPDATE_P(return_value), time_str, time_str_len, format_str, timezone_object, PHP_DATE_INIT_FORMAT)) {
|
||||
zval_ptr_dtor(return_value);
|
||||
RETURN_FALSE;
|
||||
@@ -2673,7 +2679,9 @@ PHP_METHOD(DateTime, createFromImmutable)
|
||||
old_obj = Z_PHPDATE_P(datetimeimmutable_object);
|
||||
DATE_CHECK_INITIALIZED(old_obj->time, Z_OBJCE_P(datetimeimmutable_object));
|
||||
|
||||
php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_date, return_value);
|
||||
if (object_init_ex(return_value, execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_date) != SUCCESS) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
new_obj = Z_PHPDATE_P(return_value);
|
||||
|
||||
new_obj->time = timelib_time_clone(old_obj->time);
|
||||
@@ -2694,7 +2702,9 @@ PHP_METHOD(DateTime, createFromInterface)
|
||||
old_obj = Z_PHPDATE_P(datetimeinterface_object);
|
||||
DATE_CHECK_INITIALIZED(old_obj->time, Z_OBJCE_P(datetimeinterface_object));
|
||||
|
||||
php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_date, return_value);
|
||||
if (object_init_ex(return_value, execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_date) != SUCCESS) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
new_obj = Z_PHPDATE_P(return_value);
|
||||
|
||||
new_obj->time = timelib_time_clone(old_obj->time);
|
||||
@@ -2712,7 +2722,9 @@ PHP_METHOD(DateTime, createFromTimestamp)
|
||||
Z_PARAM_NUMBER(value)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_date, &new_object);
|
||||
if (object_init_ex(&new_object, execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_date) != SUCCESS) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
new_dateobj = Z_PHPDATE_P(&new_object);
|
||||
|
||||
switch (Z_TYPE_P(value)) {
|
||||
@@ -2748,7 +2760,9 @@ PHP_METHOD(DateTimeImmutable, createFromMutable)
|
||||
old_obj = Z_PHPDATE_P(datetime_object);
|
||||
DATE_CHECK_INITIALIZED(old_obj->time, Z_OBJCE_P(datetime_object));
|
||||
|
||||
php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_immutable, return_value);
|
||||
if (object_init_ex(return_value, execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_immutable) != SUCCESS) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
new_obj = Z_PHPDATE_P(return_value);
|
||||
|
||||
new_obj->time = timelib_time_clone(old_obj->time);
|
||||
@@ -2769,7 +2783,9 @@ PHP_METHOD(DateTimeImmutable, createFromInterface)
|
||||
old_obj = Z_PHPDATE_P(datetimeinterface_object);
|
||||
DATE_CHECK_INITIALIZED(old_obj->time, Z_OBJCE_P(datetimeinterface_object));
|
||||
|
||||
php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_immutable, return_value);
|
||||
if (object_init_ex(return_value, execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_immutable) != SUCCESS) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
new_obj = Z_PHPDATE_P(return_value);
|
||||
|
||||
new_obj->time = timelib_time_clone(old_obj->time);
|
||||
@@ -2787,7 +2803,9 @@ PHP_METHOD(DateTimeImmutable, createFromTimestamp)
|
||||
Z_PARAM_NUMBER(value)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_immutable, &new_object);
|
||||
if (object_init_ex(&new_object, execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_immutable) != SUCCESS) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
new_dateobj = Z_PHPDATE_P(&new_object);
|
||||
|
||||
switch (Z_TYPE_P(value)) {
|
||||
@@ -5108,7 +5126,9 @@ PHP_METHOD(DatePeriod, createFromISO8601String)
|
||||
Z_PARAM_LONG(options)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
object_init_ex(return_value, execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_period);
|
||||
if (object_init_ex(return_value, execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_period) != SUCCESS) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
dpobj = Z_PHPPERIOD_P(return_value);
|
||||
|
||||
dpobj->current = NULL;
|
||||
|
||||
82
ext/date/tests/instantiate_uninstantiable_classes.phpt
Normal file
82
ext/date/tests/instantiate_uninstantiable_classes.phpt
Normal file
@@ -0,0 +1,82 @@
|
||||
--TEST--
|
||||
Instantiating uninstantiable classes via static constructors
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
abstract class MyDatePeriod extends DatePeriod {
|
||||
public abstract function foo();
|
||||
}
|
||||
|
||||
abstract class MyDateTime extends DateTime {
|
||||
public abstract function foo();
|
||||
}
|
||||
|
||||
abstract class MyDateTimeImmutable extends DateTimeImmutable {
|
||||
public abstract function foo();
|
||||
}
|
||||
|
||||
try {
|
||||
MyDatePeriod::createFromISO8601String('R5');
|
||||
} catch (Error $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
|
||||
try {
|
||||
MyDateTime::createFromFormat('Y-m-d', '2025-01-01');
|
||||
} catch (Error $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
|
||||
try {
|
||||
MyDateTime::createFromImmutable(new DateTimeImmutable());
|
||||
} catch (Error $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
|
||||
try {
|
||||
MyDateTime::createFromInterface(new DateTimeImmutable());
|
||||
} catch (Error $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
|
||||
try {
|
||||
MyDateTime::createFromTimestamp(0);
|
||||
} catch (Error $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
|
||||
try {
|
||||
MyDateTimeImmutable::createFromFormat('Y-m-d', '2025-01-01');
|
||||
} catch (Error $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
|
||||
try {
|
||||
MyDateTimeImmutable::createFromMutable(new DateTime());
|
||||
} catch (Error $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
|
||||
try {
|
||||
MyDateTimeImmutable::createFromInterface(new DateTime());
|
||||
} catch (Error $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
|
||||
try {
|
||||
MyDateTimeImmutable::createFromTimestamp(0);
|
||||
} catch (Error $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
Cannot instantiate abstract class MyDatePeriod
|
||||
Cannot instantiate abstract class MyDateTime
|
||||
Cannot instantiate abstract class MyDateTime
|
||||
Cannot instantiate abstract class MyDateTime
|
||||
Cannot instantiate abstract class MyDateTime
|
||||
Cannot instantiate abstract class MyDateTimeImmutable
|
||||
Cannot instantiate abstract class MyDateTimeImmutable
|
||||
Cannot instantiate abstract class MyDateTimeImmutable
|
||||
Cannot instantiate abstract class MyDateTimeImmutable
|
||||
Reference in New Issue
Block a user