From 94cec4216ac00c00307ea547c887c84f7223db6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Wed, 11 May 2022 13:42:53 +0200 Subject: [PATCH 1/4] Declare DatePeriod properties --- ext/date/php_date.c | 157 ++++++++++++--------- ext/date/php_date.stub.php | 7 + ext/date/php_date_arginfo.h | 42 +++++- ext/date/tests/DatePeriod_properties2.phpt | 30 ++-- 4 files changed, 155 insertions(+), 81 deletions(-) diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 5d2fb5b79b260..10b0be47beef2 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -299,19 +299,22 @@ static HashTable *date_object_get_properties_for(zend_object *object, zend_prop_ static HashTable *date_object_get_gc_interval(zend_object *object, zval **table, int *n); static HashTable *date_object_get_properties_interval(zend_object *object); static HashTable *date_object_get_gc_period(zend_object *object, zval **table, int *n); -static HashTable *date_object_get_properties_period(zend_object *object); static HashTable *date_object_get_properties_for_timezone(zend_object *object, zend_prop_purpose purpose); static HashTable *date_object_get_gc_timezone(zend_object *object, zval **table, int *n); static HashTable *date_object_get_debug_info_timezone(zend_object *object, int *is_temp); static void php_timezone_to_string(php_timezone_obj *tzobj, zval *zv); +static void create_date_period_datetime(timelib_time *datetime, zend_class_entry *ce, zval *zv); +static void create_date_period_interval(timelib_rel_time *interval, zval *zv); +static void initialize_date_period_properties(php_period_obj *period_obj); + static int date_interval_compare_objects(zval *o1, zval *o2); static zval *date_interval_read_property(zend_object *object, zend_string *member, int type, void **cache_slot, zval *rv); static zval *date_interval_write_property(zend_object *object, zend_string *member, zval *value, void **cache_slot); static zval *date_interval_get_property_ptr_ptr(zend_object *object, zend_string *member, int type, void **cache_slot); +static zval *date_period_get_property_ptr_ptr(zend_object *object, zend_string *name, int type, void **cache_slot); static zval *date_period_read_property(zend_object *object, zend_string *name, int type, void **cache_slot, zval *rv); static zval *date_period_write_property(zend_object *object, zend_string *name, zval *value, void **cache_slot); -static zval *date_period_get_property_ptr_ptr(zend_object *object, zend_string *name, int type, void **cache_slot); static int date_object_compare_timezone(zval *tz1, zval *tz2); @@ -1491,10 +1494,21 @@ static void date_period_it_move_forward(zend_object_iterator *iter) { date_period_it *iterator = (date_period_it *)iter; php_period_obj *object = Z_PHPPERIOD_P(&iterator->intern.data); - timelib_time *it_time = object->current; + timelib_time *it_time = object->current; + zval current_zv; date_period_advance(it_time, object->interval); + if (UNEXPECTED(!object->std.properties)) { + rebuild_object_properties(&object->std); + } + + create_date_period_datetime(object->current, object->start_ce, ¤t_zv); + zend_string *property_name = zend_string_init("current", sizeof("current") - 1, 0); + zend_std_write_property(&object->std, property_name, ¤t_zv, NULL); + zval_ptr_dtor(¤t_zv); + zend_string_release(property_name); + iterator->current_index++; date_period_it_invalidate_current(iter); } @@ -1657,9 +1671,8 @@ static void date_register_classes(void) /* {{{ */ date_object_handlers_period.offset = XtOffsetOf(php_period_obj, std); date_object_handlers_period.free_obj = date_object_free_storage_period; date_object_handlers_period.clone_obj = date_object_clone_period; - date_object_handlers_period.get_properties = date_object_get_properties_period; - date_object_handlers_period.get_property_ptr_ptr = date_period_get_property_ptr_ptr; date_object_handlers_period.get_gc = date_object_get_gc_period; + date_object_handlers_period.get_property_ptr_ptr = date_period_get_property_ptr_ptr; date_object_handlers_period.read_property = date_period_read_property; date_object_handlers_period.write_property = date_period_write_property; } /* }}} */ @@ -4502,6 +4515,8 @@ PHP_METHOD(DatePeriod, __construct) dpobj->recurrences = recurrences + dpobj->include_start_date + dpobj->include_end_date; dpobj->initialized = 1; + + initialize_date_period_properties(dpobj); } /* }}} */ @@ -4965,45 +4980,16 @@ static void date_period_object_to_hash(php_period_obj *period_obj, HashTable *pr { zval zv; - if (period_obj->start) { - php_date_obj *date_obj; - object_init_ex(&zv, period_obj->start_ce); - date_obj = Z_PHPDATE_P(&zv); - date_obj->time = timelib_time_clone(period_obj->start); - } else { - ZVAL_NULL(&zv); - } + create_date_period_datetime(period_obj->start, period_obj->start_ce, &zv); zend_hash_str_update(props, "start", sizeof("start")-1, &zv); - if (period_obj->current) { - php_date_obj *date_obj; - object_init_ex(&zv, period_obj->start_ce); - date_obj = Z_PHPDATE_P(&zv); - date_obj->time = timelib_time_clone(period_obj->current); - } else { - ZVAL_NULL(&zv); - } + create_date_period_datetime(period_obj->current, period_obj->start_ce, &zv); zend_hash_str_update(props, "current", sizeof("current")-1, &zv); - if (period_obj->end) { - php_date_obj *date_obj; - object_init_ex(&zv, period_obj->start_ce); - date_obj = Z_PHPDATE_P(&zv); - date_obj->time = timelib_time_clone(period_obj->end); - } else { - ZVAL_NULL(&zv); - } + create_date_period_datetime(period_obj->end, period_obj->start_ce, &zv); zend_hash_str_update(props, "end", sizeof("end")-1, &zv); - if (period_obj->interval) { - php_interval_obj *interval_obj; - object_init_ex(&zv, date_ce_interval); - interval_obj = Z_PHPINTERVAL_P(&zv); - interval_obj->diff = timelib_rel_time_clone(period_obj->interval); - interval_obj->initialized = 1; - } else { - ZVAL_NULL(&zv); - } + create_date_period_interval(period_obj->interval, &zv); zend_hash_str_update(props, "interval", sizeof("interval")-1, &zv); /* converted to larger type (int->long); must check when unserializing */ @@ -5017,22 +5003,6 @@ static void date_period_object_to_hash(php_period_obj *period_obj, HashTable *pr zend_hash_str_update(props, "include_end_date", sizeof("include_end_date")-1, &zv); } -static HashTable *date_object_get_properties_period(zend_object *object) /* {{{ */ -{ - HashTable *props; - php_period_obj *period_obj; - - period_obj = php_period_obj_from_obj(object); - props = zend_std_get_properties(object); - if (!period_obj->start) { - return props; - } - - date_period_object_to_hash(period_obj, props); - - return props; -} /* }}} */ - static bool php_date_period_initialize_from_hash(php_period_obj *period_obj, HashTable *myht) /* {{{ */ { zval *ht_entry; @@ -5118,6 +5088,8 @@ static bool php_date_period_initialize_from_hash(php_period_obj *period_obj, Has period_obj->initialized = 1; + initialize_date_period_properties(period_obj); + return 1; } /* }}} */ @@ -5201,10 +5173,10 @@ PHP_METHOD(DatePeriod, __wakeup) } /* }}} */ -/* {{{ date_period_is_magic_property +/* {{{ date_period_is_internal_property * Common for date_period_read_property() and date_period_write_property() functions */ -static bool date_period_is_magic_property(zend_string *name) +static bool date_period_is_internal_property(zend_string *name) { if (zend_string_equals_literal(name, "recurrences") || zend_string_equals_literal(name, "include_start_date") @@ -5224,38 +5196,87 @@ static bool date_period_is_magic_property(zend_string *name) static zval *date_period_read_property(zend_object *object, zend_string *name, int type, void **cache_slot, zval *rv) { if (type != BP_VAR_IS && type != BP_VAR_R) { - if (date_period_is_magic_property(name)) { - zend_throw_error(NULL, "Retrieval of DatePeriod->%s for modification is unsupported", ZSTR_VAL(name)); + if (date_period_is_internal_property(name)) { + zend_throw_error(NULL, "Cannot modify readonly property DatePeriod::$%s", ZSTR_VAL(name)); return &EG(uninitialized_zval); } } - object->handlers->get_properties(object); /* build properties hash table */ - return zend_std_read_property(object, name, type, cache_slot, rv); } /* }}} */ -/* {{{ date_period_write_property */ static zval *date_period_write_property(zend_object *object, zend_string *name, zval *value, void **cache_slot) { - if (date_period_is_magic_property(name)) { - zend_throw_error(NULL, "Writing to DatePeriod->%s is unsupported", ZSTR_VAL(name)); + if (zend_string_equals_literal(name, "current")) { + zend_throw_error(NULL, "Cannot modify readonly property DatePeriod::$%s", ZSTR_VAL(name)); return value; } return zend_std_write_property(object, name, value, cache_slot); } -/* }}} */ -/* {{{ date_period_get_property_ptr_ptr */ static zval *date_period_get_property_ptr_ptr(zend_object *object, zend_string *name, int type, void **cache_slot) { - if (date_period_is_magic_property(name)) { - zend_throw_error(NULL, "Retrieval of DatePeriod->%s for modification is unsupported", ZSTR_VAL(name)); + if (zend_string_equals_literal(name, "current")) { + zend_throw_error(NULL, "Cannot modify readonly property DatePeriod::$%s", ZSTR_VAL(name)); return &EG(error_zval); } return zend_std_get_property_ptr_ptr(object, name, type, cache_slot); } -/* }}} */ + +static void create_date_period_datetime(timelib_time *datetime, zend_class_entry *ce, zval *zv) +{ + if (datetime) { + php_date_obj *date_obj; + object_init_ex(zv, ce); + date_obj = Z_PHPDATE_P(zv); + date_obj->time = timelib_time_clone(datetime); + } else { + ZVAL_NULL(zv); + } +} + +static void create_date_period_interval(timelib_rel_time *interval, zval *zv) +{ + if (interval) { + php_interval_obj *interval_obj; + object_init_ex(zv, date_ce_interval); + interval_obj = Z_PHPINTERVAL_P(zv); + interval_obj->diff = timelib_rel_time_clone(interval); + interval_obj->initialized = 1; + } else { + ZVAL_NULL(zv); + } +} + +static void initialize_date_period_properties(php_period_obj *period_obj) +{ + zval start_zv, current_zv, end_zv, interval_zv; + + if (UNEXPECTED(!period_obj->std.properties)) { + rebuild_object_properties(&period_obj->std); + } + + create_date_period_datetime(period_obj->start, period_obj->start_ce, &start_zv); + zend_update_property(date_ce_period, &period_obj->std, "start", sizeof("start") - 1, &start_zv); + zval_ptr_dtor(&start_zv); + + create_date_period_datetime(period_obj->current, period_obj->start_ce, ¤t_zv); + zend_string *property_name = zend_string_init("current", sizeof("current") - 1, 0); + zend_std_write_property(&period_obj->std, property_name, ¤t_zv, NULL); + zval_ptr_dtor(¤t_zv); + zend_string_release(property_name); + + create_date_period_datetime(period_obj->end, period_obj->start_ce, &end_zv); + zend_update_property(date_ce_period, &period_obj->std, "end", sizeof("end") - 1, &end_zv); + zval_ptr_dtor(&end_zv); + + create_date_period_interval(period_obj->interval, &interval_zv); + zend_update_property(date_ce_period, &period_obj->std, "interval", sizeof("interval") - 1, &interval_zv); + zval_ptr_dtor(&interval_zv); + + zend_update_property_long(date_ce_period, &period_obj->std, "recurrences", sizeof("recurrences") - 1, (zend_long) period_obj->recurrences); + zend_update_property_bool(date_ce_period, &period_obj->std, "include_start_date", sizeof("include_start_date") - 1, period_obj->include_start_date); +} diff --git a/ext/date/php_date.stub.php b/ext/date/php_date.stub.php index 68b16a07a12f1..05817b7d3ce4c 100644 --- a/ext/date/php_date.stub.php +++ b/ext/date/php_date.stub.php @@ -683,6 +683,13 @@ public static function __set_state(array $array): DateInterval {} class DatePeriod implements IteratorAggregate { + public readonly ?DateTimeInterface $start; + public ?DateTimeInterface $current; + public readonly ?DateTimeInterface $end; + public readonly ?DateInterval $interval; + public readonly int $recurrences; + public readonly bool $include_start_date; + /** * @var int * @cname PHP_DATE_PERIOD_EXCLUDE_START_DATE diff --git a/ext/date/php_date_arginfo.h b/ext/date/php_date_arginfo.h index 2183458ec98fa..34e7405ec4337 100644 --- a/ext/date/php_date_arginfo.h +++ b/ext/date/php_date_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 2cdf90d626d020b7e746cbccdb87833720d87132 */ + * Stub hash: d5f960d58c9577c755164d4372a2f4d70a3b1aaf */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_strtotime, 0, 1, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, datetime, IS_STRING, 0) @@ -1026,5 +1026,45 @@ static zend_class_entry *register_class_DatePeriod(zend_class_entry *class_entry zend_declare_class_constant_ex(class_entry, const_INCLUDE_END_DATE_name, &const_INCLUDE_END_DATE_value, ZEND_ACC_PUBLIC, NULL); zend_string_release(const_INCLUDE_END_DATE_name); + zend_string *property_start_class_DateTimeInterface = zend_string_init("DateTimeInterface", sizeof("DateTimeInterface")-1, 1); + zval property_start_default_value; + ZVAL_UNDEF(&property_start_default_value); + zend_string *property_start_name = zend_string_init("start", sizeof("start") - 1, 1); + zend_declare_typed_property(class_entry, property_start_name, &property_start_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_start_class_DateTimeInterface, 0, MAY_BE_NULL)); + zend_string_release(property_start_name); + + zend_string *property_current_class_DateTimeInterface = zend_string_init("DateTimeInterface", sizeof("DateTimeInterface")-1, 1); + zval property_current_default_value; + ZVAL_UNDEF(&property_current_default_value); + zend_string *property_current_name = zend_string_init("current", sizeof("current") - 1, 1); + zend_declare_typed_property(class_entry, property_current_name, &property_current_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_current_class_DateTimeInterface, 0, MAY_BE_NULL)); + zend_string_release(property_current_name); + + zend_string *property_end_class_DateTimeInterface = zend_string_init("DateTimeInterface", sizeof("DateTimeInterface")-1, 1); + zval property_end_default_value; + ZVAL_UNDEF(&property_end_default_value); + zend_string *property_end_name = zend_string_init("end", sizeof("end") - 1, 1); + zend_declare_typed_property(class_entry, property_end_name, &property_end_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_end_class_DateTimeInterface, 0, MAY_BE_NULL)); + zend_string_release(property_end_name); + + zend_string *property_interval_class_DateInterval = zend_string_init("DateInterval", sizeof("DateInterval")-1, 1); + zval property_interval_default_value; + ZVAL_UNDEF(&property_interval_default_value); + zend_string *property_interval_name = zend_string_init("interval", sizeof("interval") - 1, 1); + zend_declare_typed_property(class_entry, property_interval_name, &property_interval_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_interval_class_DateInterval, 0, MAY_BE_NULL)); + zend_string_release(property_interval_name); + + zval property_recurrences_default_value; + ZVAL_UNDEF(&property_recurrences_default_value); + zend_string *property_recurrences_name = zend_string_init("recurrences", sizeof("recurrences") - 1, 1); + zend_declare_typed_property(class_entry, property_recurrences_name, &property_recurrences_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(property_recurrences_name); + + zval property_include_start_date_default_value; + ZVAL_UNDEF(&property_include_start_date_default_value); + zend_string *property_include_start_date_name = zend_string_init("include_start_date", sizeof("include_start_date") - 1, 1); + zend_declare_typed_property(class_entry, property_include_start_date_name, &property_include_start_date_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_string_release(property_include_start_date_name); + return class_entry; } diff --git a/ext/date/tests/DatePeriod_properties2.phpt b/ext/date/tests/DatePeriod_properties2.phpt index 044746c024abc..376254698f9bb 100644 --- a/ext/date/tests/DatePeriod_properties2.phpt +++ b/ext/date/tests/DatePeriod_properties2.phpt @@ -30,17 +30,23 @@ foreach ($properties as $property) { } } +try { + $period->start->modify("+1 hour"); +} catch (Error $e) { + echo $e->getMessage() . "\n"; +} + ?> --EXPECT-- -Writing to DatePeriod->recurrences is unsupported -Retrieval of DatePeriod->recurrences for modification is unsupported -Writing to DatePeriod->include_start_date is unsupported -Retrieval of DatePeriod->include_start_date for modification is unsupported -Writing to DatePeriod->start is unsupported -Retrieval of DatePeriod->start for modification is unsupported -Writing to DatePeriod->current is unsupported -Retrieval of DatePeriod->current for modification is unsupported -Writing to DatePeriod->end is unsupported -Retrieval of DatePeriod->end for modification is unsupported -Writing to DatePeriod->interval is unsupported -Retrieval of DatePeriod->interval for modification is unsupported +Cannot modify readonly property DatePeriod::$recurrences +Cannot modify readonly property DatePeriod::$recurrences +Cannot modify readonly property DatePeriod::$include_start_date +Cannot modify readonly property DatePeriod::$include_start_date +Cannot modify readonly property DatePeriod::$start +Cannot modify readonly property DatePeriod::$start +Cannot modify readonly property DatePeriod::$current +Cannot modify readonly property DatePeriod::$current +Cannot modify readonly property DatePeriod::$end +Cannot modify readonly property DatePeriod::$end +Cannot modify readonly property DatePeriod::$interval +Cannot modify readonly property DatePeriod::$interval From 38b143707085a1a9c1a11a9e03a5723abae4259c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Wed, 11 May 2022 20:46:10 +0200 Subject: [PATCH 2/4] Fix test --- ext/opcache/tests/jit/bug80634.phpt | 2 +- ext/opcache/tests/jit/preload_bug80634.inc | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ext/opcache/tests/jit/bug80634.phpt b/ext/opcache/tests/jit/bug80634.phpt index 328168c528505..1eb159a38f4c5 100644 --- a/ext/opcache/tests/jit/bug80634.phpt +++ b/ext/opcache/tests/jit/bug80634.phpt @@ -19,7 +19,7 @@ if (PHP_OS_FAMILY == 'Windows') die('skip Preloading is not supported on Windows $v = new SomeClass(5); ?> --EXPECTF-- -Fatal error: Uncaught Error: Writing to DatePeriod->interval is unsupported in %spreload_bug80634.inc:7 +Fatal error: Uncaught Error: Cannot modify readonly property DatePeriod::$current in %spreload_bug80634.inc:7 Stack trace: #0 %sbug80634.php(2): SomeClass->__construct(5) #1 {main} diff --git a/ext/opcache/tests/jit/preload_bug80634.inc b/ext/opcache/tests/jit/preload_bug80634.inc index feee9ec9706d2..1fa324381a751 100644 --- a/ext/opcache/tests/jit/preload_bug80634.inc +++ b/ext/opcache/tests/jit/preload_bug80634.inc @@ -1,10 +1,10 @@ interval = $v; - var_dump($this->interval); + $this->current = $v; + var_dump($this->current); } -} \ No newline at end of file +} From a8c369fe78b11170c5c5f738fde0cd040d5961c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Thu, 12 May 2022 16:46:51 +0200 Subject: [PATCH 3/4] Fix code review --- ext/date/php_date.c | 118 ++++++++++++++++++------------------ ext/date/php_date.stub.php | 1 + ext/date/php_date_arginfo.h | 2 +- 3 files changed, 60 insertions(+), 61 deletions(-) diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 10b0be47beef2..8be6c6247e243 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -304,17 +304,13 @@ static HashTable *date_object_get_gc_timezone(zend_object *object, zval **table, static HashTable *date_object_get_debug_info_timezone(zend_object *object, int *is_temp); static void php_timezone_to_string(php_timezone_obj *tzobj, zval *zv); -static void create_date_period_datetime(timelib_time *datetime, zend_class_entry *ce, zval *zv); -static void create_date_period_interval(timelib_rel_time *interval, zval *zv); -static void initialize_date_period_properties(php_period_obj *period_obj); - static int date_interval_compare_objects(zval *o1, zval *o2); static zval *date_interval_read_property(zend_object *object, zend_string *member, int type, void **cache_slot, zval *rv); static zval *date_interval_write_property(zend_object *object, zend_string *member, zval *value, void **cache_slot); static zval *date_interval_get_property_ptr_ptr(zend_object *object, zend_string *member, int type, void **cache_slot); -static zval *date_period_get_property_ptr_ptr(zend_object *object, zend_string *name, int type, void **cache_slot); static zval *date_period_read_property(zend_object *object, zend_string *name, int type, void **cache_slot, zval *rv); static zval *date_period_write_property(zend_object *object, zend_string *name, zval *value, void **cache_slot); +static zval *date_period_get_property_ptr_ptr(zend_object *object, zend_string *name, int type, void **cache_slot); static int date_object_compare_timezone(zval *tz1, zval *tz2); @@ -1399,6 +1395,63 @@ PHP_FUNCTION(getdate) } /* }}} */ +static void create_date_period_datetime(timelib_time *datetime, zend_class_entry *ce, zval *zv) +{ + if (datetime) { + php_date_obj *date_obj; + + object_init_ex(zv, ce); + date_obj = Z_PHPDATE_P(zv); + date_obj->time = timelib_time_clone(datetime); + } else { + ZVAL_NULL(zv); + } +} + +static void create_date_period_interval(timelib_rel_time *interval, zval *zv) +{ + if (interval) { + php_interval_obj *interval_obj; + + object_init_ex(zv, date_ce_interval); + interval_obj = Z_PHPINTERVAL_P(zv); + interval_obj->diff = timelib_rel_time_clone(interval); + interval_obj->initialized = 1; + } else { + ZVAL_NULL(zv); + } +} + +static void initialize_date_period_properties(php_period_obj *period_obj) +{ + zval start_zv, current_zv, end_zv, interval_zv; + + if (UNEXPECTED(!period_obj->std.properties)) { + rebuild_object_properties(&period_obj->std); + } + + create_date_period_datetime(period_obj->start, period_obj->start_ce, &start_zv); + zend_update_property(date_ce_period, &period_obj->std, "start", sizeof("start") - 1, &start_zv); + zval_ptr_dtor(&start_zv); + + create_date_period_datetime(period_obj->current, period_obj->start_ce, ¤t_zv); + zend_string *property_name = zend_string_init("current", sizeof("current") - 1, 0); + zend_std_write_property(&period_obj->std, property_name, ¤t_zv, NULL); + zval_ptr_dtor(¤t_zv); + zend_string_release(property_name); + + create_date_period_datetime(period_obj->end, period_obj->start_ce, &end_zv); + zend_update_property(date_ce_period, &period_obj->std, "end", sizeof("end") - 1, &end_zv); + zval_ptr_dtor(&end_zv); + + create_date_period_interval(period_obj->interval, &interval_zv); + zend_update_property(date_ce_period, &period_obj->std, "interval", sizeof("interval") - 1, &interval_zv); + zval_ptr_dtor(&interval_zv); + + zend_update_property_long(date_ce_period, &period_obj->std, "recurrences", sizeof("recurrences") - 1, (zend_long) period_obj->recurrences); + zend_update_property_bool(date_ce_period, &period_obj->std, "include_start_date", sizeof("include_start_date") - 1, period_obj->include_start_date); +} + /* define an overloaded iterator structure */ typedef struct { zend_object_iterator intern; @@ -5225,58 +5278,3 @@ static zval *date_period_get_property_ptr_ptr(zend_object *object, zend_string * return zend_std_get_property_ptr_ptr(object, name, type, cache_slot); } - -static void create_date_period_datetime(timelib_time *datetime, zend_class_entry *ce, zval *zv) -{ - if (datetime) { - php_date_obj *date_obj; - object_init_ex(zv, ce); - date_obj = Z_PHPDATE_P(zv); - date_obj->time = timelib_time_clone(datetime); - } else { - ZVAL_NULL(zv); - } -} - -static void create_date_period_interval(timelib_rel_time *interval, zval *zv) -{ - if (interval) { - php_interval_obj *interval_obj; - object_init_ex(zv, date_ce_interval); - interval_obj = Z_PHPINTERVAL_P(zv); - interval_obj->diff = timelib_rel_time_clone(interval); - interval_obj->initialized = 1; - } else { - ZVAL_NULL(zv); - } -} - -static void initialize_date_period_properties(php_period_obj *period_obj) -{ - zval start_zv, current_zv, end_zv, interval_zv; - - if (UNEXPECTED(!period_obj->std.properties)) { - rebuild_object_properties(&period_obj->std); - } - - create_date_period_datetime(period_obj->start, period_obj->start_ce, &start_zv); - zend_update_property(date_ce_period, &period_obj->std, "start", sizeof("start") - 1, &start_zv); - zval_ptr_dtor(&start_zv); - - create_date_period_datetime(period_obj->current, period_obj->start_ce, ¤t_zv); - zend_string *property_name = zend_string_init("current", sizeof("current") - 1, 0); - zend_std_write_property(&period_obj->std, property_name, ¤t_zv, NULL); - zval_ptr_dtor(¤t_zv); - zend_string_release(property_name); - - create_date_period_datetime(period_obj->end, period_obj->start_ce, &end_zv); - zend_update_property(date_ce_period, &period_obj->std, "end", sizeof("end") - 1, &end_zv); - zval_ptr_dtor(&end_zv); - - create_date_period_interval(period_obj->interval, &interval_zv); - zend_update_property(date_ce_period, &period_obj->std, "interval", sizeof("interval") - 1, &interval_zv); - zval_ptr_dtor(&interval_zv); - - zend_update_property_long(date_ce_period, &period_obj->std, "recurrences", sizeof("recurrences") - 1, (zend_long) period_obj->recurrences); - zend_update_property_bool(date_ce_period, &period_obj->std, "include_start_date", sizeof("include_start_date") - 1, period_obj->include_start_date); -} diff --git a/ext/date/php_date.stub.php b/ext/date/php_date.stub.php index 05817b7d3ce4c..d512209a4c7ae 100644 --- a/ext/date/php_date.stub.php +++ b/ext/date/php_date.stub.php @@ -684,6 +684,7 @@ public static function __set_state(array $array): DateInterval {} class DatePeriod implements IteratorAggregate { public readonly ?DateTimeInterface $start; + /** @readonly */ public ?DateTimeInterface $current; public readonly ?DateTimeInterface $end; public readonly ?DateInterval $interval; diff --git a/ext/date/php_date_arginfo.h b/ext/date/php_date_arginfo.h index 34e7405ec4337..98065090d4480 100644 --- a/ext/date/php_date_arginfo.h +++ b/ext/date/php_date_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: d5f960d58c9577c755164d4372a2f4d70a3b1aaf */ + * Stub hash: dc54d1976c4fb2c5d1b7ee0bfe566abc8847c554 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_strtotime, 0, 1, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, datetime, IS_STRING, 0) From cf55a18c9abcec6ebbd2a9e254dfe01b10d7b4a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Tue, 24 May 2022 09:27:06 +0200 Subject: [PATCH 4/4] Fix conflicts --- ext/date/php_date.c | 1 + ext/date/php_date.stub.php | 17 +++++++++-------- ext/date/php_date_arginfo.h | 8 +++++++- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 8be6c6247e243..8aa544e7436a9 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -1450,6 +1450,7 @@ static void initialize_date_period_properties(php_period_obj *period_obj) zend_update_property_long(date_ce_period, &period_obj->std, "recurrences", sizeof("recurrences") - 1, (zend_long) period_obj->recurrences); zend_update_property_bool(date_ce_period, &period_obj->std, "include_start_date", sizeof("include_start_date") - 1, period_obj->include_start_date); + zend_update_property_bool(date_ce_period, &period_obj->std, "include_end_date", sizeof("include_end_date") - 1, period_obj->include_end_date); } /* define an overloaded iterator structure */ diff --git a/ext/date/php_date.stub.php b/ext/date/php_date.stub.php index d512209a4c7ae..4edd19f36f1ca 100644 --- a/ext/date/php_date.stub.php +++ b/ext/date/php_date.stub.php @@ -683,14 +683,6 @@ public static function __set_state(array $array): DateInterval {} class DatePeriod implements IteratorAggregate { - public readonly ?DateTimeInterface $start; - /** @readonly */ - public ?DateTimeInterface $current; - public readonly ?DateTimeInterface $end; - public readonly ?DateInterval $interval; - public readonly int $recurrences; - public readonly bool $include_start_date; - /** * @var int * @cname PHP_DATE_PERIOD_EXCLUDE_START_DATE @@ -702,6 +694,15 @@ class DatePeriod implements IteratorAggregate */ public const INCLUDE_END_DATE = UNKNOWN; + public readonly ?DateTimeInterface $start; + /** @readonly */ + public ?DateTimeInterface $current; + public readonly ?DateTimeInterface $end; + public readonly ?DateInterval $interval; + public readonly int $recurrences; + public readonly bool $include_start_date; + public readonly bool $include_end_date; + /** * @param DateTimeInterface|string $start * @param DateInterval|int $interval diff --git a/ext/date/php_date_arginfo.h b/ext/date/php_date_arginfo.h index 98065090d4480..36f8cfaf5b4cc 100644 --- a/ext/date/php_date_arginfo.h +++ b/ext/date/php_date_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: dc54d1976c4fb2c5d1b7ee0bfe566abc8847c554 */ + * Stub hash: 7ef8c504e35ca49f2c7442bd572b196587a36b7b */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_strtotime, 0, 1, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, datetime, IS_STRING, 0) @@ -1066,5 +1066,11 @@ static zend_class_entry *register_class_DatePeriod(zend_class_entry *class_entry zend_declare_typed_property(class_entry, property_include_start_date_name, &property_include_start_date_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); zend_string_release(property_include_start_date_name); + zval property_include_end_date_default_value; + ZVAL_UNDEF(&property_include_end_date_default_value); + zend_string *property_include_end_date_name = zend_string_init("include_end_date", sizeof("include_end_date") - 1, 1); + zend_declare_typed_property(class_entry, property_include_end_date_name, &property_include_end_date_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); + zend_string_release(property_include_end_date_name); + return class_entry; }