diff --git a/NEWS b/NEWS index b3bf2f709ae..115cb7a879a 100644 --- a/NEWS +++ b/NEWS @@ -29,6 +29,8 @@ PHP NEWS . Fix GH-10447 ('p' format specifier does not yield 'Z' for 00:00). (Derick) . Fix GH-10152 (Custom properties of Date's child classes are not serialised). (Derick) + . Fixed bug GH-10747 (Private and protected properties in serialized Date* + objects throw). (Derick) - FFI: . Fixed incorrect bitshifting and masking in ffi bitfield. (nielsdos) diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 9bfc4e19740..3ba577c7b2d 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -565,6 +565,36 @@ PHPAPI timelib_tzinfo *get_timezone_info(void) } return tzi; } + +static void update_property(zend_object *object, zend_string *key, zval *prop_val) +{ + if (ZSTR_VAL(key)[0] == '\0') { // not public + const char *class_name, *prop_name; + size_t prop_name_len; + + if (zend_unmangle_property_name_ex(key, &class_name, &prop_name, &prop_name_len) == SUCCESS) { + if (class_name[0] != '*') { // private + zend_string *cname; + zend_class_entry *ce; + + cname = zend_string_init(class_name, strlen(class_name), 0); + ce = zend_lookup_class(cname); + + if (ce) { + zend_update_property(ce, object, prop_name, prop_name_len, prop_val); + } + + zend_string_release_ex(cname, 0); + } else { // protected + zend_update_property(object->ce, object, prop_name, prop_name_len, prop_val); + } + } + return; + } + + // public + zend_update_property(object->ce, object, ZSTR_VAL(key), ZSTR_LEN(key), prop_val); +} /* }}} */ @@ -2794,7 +2824,7 @@ static void restore_custom_datetime_properties(zval *object, HashTable *myht) if (!prop_name || (Z_TYPE_P(prop_val) == IS_REFERENCE) || date_time_is_internal_property(prop_name)) { continue; } - add_property_zval_ex(object, ZSTR_VAL(prop_name), ZSTR_LEN(prop_name), prop_val); + update_property(Z_OBJ_P(object), prop_name, prop_val); } ZEND_HASH_FOREACH_END(); } @@ -3828,7 +3858,7 @@ static void restore_custom_datetimezone_properties(zval *object, HashTable *myht if (!prop_name || (Z_TYPE_P(prop_val) == IS_REFERENCE) || date_timezone_is_internal_property(prop_name)) { continue; } - add_property_zval_ex(object, ZSTR_VAL(prop_name), ZSTR_LEN(prop_name), prop_val); + update_property(Z_OBJ_P(object), prop_name, prop_val); } ZEND_HASH_FOREACH_END(); } @@ -4456,7 +4486,7 @@ static void restore_custom_dateinterval_properties(zval *object, HashTable *myht if (!prop_name || (Z_TYPE_P(prop_val) == IS_REFERENCE) || date_interval_is_internal_property(prop_name)) { continue; } - add_property_zval_ex(object, ZSTR_VAL(prop_name), ZSTR_LEN(prop_name), prop_val); + update_property(Z_OBJ_P(object), prop_name, prop_val); } ZEND_HASH_FOREACH_END(); } @@ -5418,7 +5448,7 @@ static void restore_custom_dateperiod_properties(zval *object, HashTable *myht) if (!prop_name || (Z_TYPE_P(prop_val) == IS_REFERENCE) || date_period_is_internal_property(prop_name)) { continue; } - add_property_zval_ex(object, ZSTR_VAL(prop_name), ZSTR_LEN(prop_name), prop_val); + update_property(Z_OBJ_P(object), prop_name, prop_val); } ZEND_HASH_FOREACH_END(); } diff --git a/ext/date/tests/gh10152.phpt b/ext/date/tests/gh10152.phpt index 7886cf90ef2..8b5ec9529e2 100644 --- a/ext/date/tests/gh10152.phpt +++ b/ext/date/tests/gh10152.phpt @@ -1,5 +1,5 @@ --TEST-- -GH-10152: Custom properties of DateTimeImmutable child classes are not serialized +Bug GH-10152 (Custom properties of DateTimeImmutable child classes are not serialized) --FILE-- myProperty); ?> --EXPECT-- diff --git a/ext/date/tests/gh10747-1.phpt b/ext/date/tests/gh10747-1.phpt new file mode 100644 index 00000000000..04f3efc1296 Binary files /dev/null and b/ext/date/tests/gh10747-1.phpt differ diff --git a/ext/date/tests/gh10747-2.phpt b/ext/date/tests/gh10747-2.phpt new file mode 100644 index 00000000000..7bda7858d88 Binary files /dev/null and b/ext/date/tests/gh10747-2.phpt differ diff --git a/ext/date/tests/gh10747-3.phpt b/ext/date/tests/gh10747-3.phpt new file mode 100644 index 00000000000..2ea11619e7b Binary files /dev/null and b/ext/date/tests/gh10747-3.phpt differ diff --git a/ext/date/tests/gh10747-4.phpt b/ext/date/tests/gh10747-4.phpt new file mode 100644 index 00000000000..500c0e320c7 Binary files /dev/null and b/ext/date/tests/gh10747-4.phpt differ diff --git a/ext/date/tests/gh10747-error.phpt b/ext/date/tests/gh10747-error.phpt new file mode 100644 index 00000000000..bfa37512172 Binary files /dev/null and b/ext/date/tests/gh10747-error.phpt differ