Skip to content

Commit b46632e

Browse files
committed
Merged pull request #8422
2 parents 90a845c + 6f2c501 commit b46632e

14 files changed

+544
-54
lines changed

ext/date/php_date.c

Lines changed: 173 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1811,28 +1811,9 @@ static HashTable *date_object_get_gc_timezone(zend_object *object, zval **table,
18111811
return zend_std_get_properties(object);
18121812
} /* }}} */
18131813

1814-
static HashTable *date_object_get_properties_for(zend_object *object, zend_prop_purpose purpose) /* {{{ */
1814+
static void date_object_to_hash(php_date_obj *dateobj, HashTable *props)
18151815
{
1816-
HashTable *props;
18171816
zval zv;
1818-
php_date_obj *dateobj;
1819-
1820-
switch (purpose) {
1821-
case ZEND_PROP_PURPOSE_DEBUG:
1822-
case ZEND_PROP_PURPOSE_SERIALIZE:
1823-
case ZEND_PROP_PURPOSE_VAR_EXPORT:
1824-
case ZEND_PROP_PURPOSE_JSON:
1825-
case ZEND_PROP_PURPOSE_ARRAY_CAST:
1826-
break;
1827-
default:
1828-
return zend_std_get_properties_for(object, purpose);
1829-
}
1830-
1831-
dateobj = php_date_obj_from_obj(object);
1832-
props = zend_array_dup(zend_std_get_properties(object));
1833-
if (!dateobj->time) {
1834-
return props;
1835-
}
18361817

18371818
/* first we add the date and time in ISO format */
18381819
ZVAL_STR(&zv, date_format("Y-m-d H:i:s.u", sizeof("Y-m-d H:i:s.u")-1, dateobj->time, 1));
@@ -1865,6 +1846,31 @@ static HashTable *date_object_get_properties_for(zend_object *object, zend_prop_
18651846
}
18661847
zend_hash_str_update(props, "timezone", sizeof("timezone")-1, &zv);
18671848
}
1849+
}
1850+
1851+
static HashTable *date_object_get_properties_for(zend_object *object, zend_prop_purpose purpose) /* {{{ */
1852+
{
1853+
HashTable *props;
1854+
php_date_obj *dateobj;
1855+
1856+
switch (purpose) {
1857+
case ZEND_PROP_PURPOSE_DEBUG:
1858+
case ZEND_PROP_PURPOSE_SERIALIZE:
1859+
case ZEND_PROP_PURPOSE_VAR_EXPORT:
1860+
case ZEND_PROP_PURPOSE_JSON:
1861+
case ZEND_PROP_PURPOSE_ARRAY_CAST:
1862+
break;
1863+
default:
1864+
return zend_std_get_properties_for(object, purpose);
1865+
}
1866+
1867+
dateobj = php_date_obj_from_obj(object);
1868+
props = zend_array_dup(zend_std_get_properties(object));
1869+
if (!dateobj->time) {
1870+
return props;
1871+
}
1872+
1873+
date_object_to_hash(dateobj, props);
18681874

18691875
return props;
18701876
} /* }}} */
@@ -1963,10 +1969,20 @@ static void php_timezone_to_string(php_timezone_obj *tzobj, zval *zv)
19631969
}
19641970
}
19651971

1972+
void date_timezone_object_to_hash(php_timezone_obj *tzobj, HashTable *props)
1973+
{
1974+
zval zv;
1975+
1976+
ZVAL_LONG(&zv, tzobj->type);
1977+
zend_hash_str_update(props, "timezone_type", strlen("timezone_type"), &zv);
1978+
1979+
php_timezone_to_string(tzobj, &zv);
1980+
zend_hash_str_update(props, "timezone", strlen("timezone"), &zv);
1981+
}
1982+
19661983
static HashTable *date_object_get_properties_for_timezone(zend_object *object, zend_prop_purpose purpose) /* {{{ */
19671984
{
19681985
HashTable *props;
1969-
zval zv;
19701986
php_timezone_obj *tzobj;
19711987

19721988
switch (purpose) {
@@ -1986,11 +2002,7 @@ static HashTable *date_object_get_properties_for_timezone(zend_object *object, z
19862002
return props;
19872003
}
19882004

1989-
ZVAL_LONG(&zv, tzobj->type);
1990-
zend_hash_str_update(props, "timezone_type", sizeof("timezone_type")-1, &zv);
1991-
1992-
php_timezone_to_string(tzobj, &zv);
1993-
zend_hash_str_update(props, "timezone", sizeof("timezone")-1, &zv);
2005+
date_timezone_object_to_hash(tzobj, props);
19942006

19952007
return props;
19962008
} /* }}} */
@@ -2623,6 +2635,84 @@ PHP_METHOD(DateTimeImmutable, __set_state)
26232635
}
26242636
/* }}} */
26252637

2638+
/* {{{ */
2639+
PHP_METHOD(DateTime, __serialize)
2640+
{
2641+
zval *object = ZEND_THIS;
2642+
php_date_obj *dateobj;
2643+
HashTable *myht;
2644+
2645+
ZEND_PARSE_PARAMETERS_NONE();
2646+
2647+
dateobj = Z_PHPDATE_P(object);
2648+
DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
2649+
2650+
array_init(return_value);
2651+
myht = Z_ARRVAL_P(return_value);
2652+
date_object_to_hash(dateobj, myht);
2653+
}
2654+
/* }}} */
2655+
2656+
/* {{{ */
2657+
PHP_METHOD(DateTimeImmutable, __serialize)
2658+
{
2659+
zval *object = ZEND_THIS;
2660+
php_date_obj *dateobj;
2661+
HashTable *myht;
2662+
2663+
ZEND_PARSE_PARAMETERS_NONE();
2664+
2665+
dateobj = Z_PHPDATE_P(object);
2666+
DATE_CHECK_INITIALIZED(dateobj->time, DateTimeImmutable);
2667+
2668+
array_init(return_value);
2669+
myht = Z_ARRVAL_P(return_value);
2670+
date_object_to_hash(dateobj, myht);
2671+
}
2672+
/* }}} */
2673+
2674+
/* {{{ */
2675+
PHP_METHOD(DateTime, __unserialize)
2676+
{
2677+
zval *object = ZEND_THIS;
2678+
php_date_obj *dateobj;
2679+
zval *array;
2680+
HashTable *myht;
2681+
2682+
ZEND_PARSE_PARAMETERS_START(1, 1)
2683+
Z_PARAM_ARRAY(array)
2684+
ZEND_PARSE_PARAMETERS_END();
2685+
2686+
dateobj = Z_PHPDATE_P(object);
2687+
myht = Z_ARRVAL_P(array);
2688+
2689+
if (!php_date_initialize_from_hash(&dateobj, myht)) {
2690+
zend_throw_error(NULL, "Invalid serialization data for DateTime object");
2691+
}
2692+
}
2693+
/* }}} */
2694+
2695+
/* {{{ */
2696+
PHP_METHOD(DateTimeImmutable, __unserialize)
2697+
{
2698+
zval *object = ZEND_THIS;
2699+
php_date_obj *dateobj;
2700+
zval *array;
2701+
HashTable *myht;
2702+
2703+
ZEND_PARSE_PARAMETERS_START(1, 1)
2704+
Z_PARAM_ARRAY(array)
2705+
ZEND_PARSE_PARAMETERS_END();
2706+
2707+
dateobj = Z_PHPDATE_P(object);
2708+
myht = Z_ARRVAL_P(array);
2709+
2710+
if (!php_date_initialize_from_hash(&dateobj, myht)) {
2711+
zend_throw_error(NULL, "Invalid serialization data for DateTimeImmutable object");
2712+
}
2713+
}
2714+
/* }}} */
2715+
26262716
/* {{{ */
26272717
PHP_METHOD(DateTime, __wakeup)
26282718
{
@@ -3040,6 +3130,12 @@ PHP_METHOD(DateTimeImmutable, sub)
30403130

30413131
static void set_timezone_from_timelib_time(php_timezone_obj *tzobj, timelib_time *t)
30423132
{
3133+
/* Free abbreviation if already set */
3134+
if (tzobj->initialized && tzobj->type == TIMELIB_ZONETYPE_ABBR) {
3135+
timelib_free(tzobj->tzi.z.abbr);
3136+
}
3137+
3138+
/* Set new values */
30433139
tzobj->initialized = 1;
30443140
tzobj->type = t->zone_type;
30453141

@@ -3416,7 +3512,7 @@ PHP_FUNCTION(date_diff)
34163512
}
34173513
/* }}} */
34183514

3419-
static zend_result timezone_initialize(php_timezone_obj *tzobj, const char *tz, size_t tz_len) /* {{{ */
3515+
static bool timezone_initialize(php_timezone_obj *tzobj, const char *tz, size_t tz_len) /* {{{ */
34203516
{
34213517
timelib_time *dummy_t = ecalloc(1, sizeof(timelib_time));
34223518
int dst, not_found;
@@ -3425,19 +3521,19 @@ static zend_result timezone_initialize(php_timezone_obj *tzobj, const char *tz,
34253521
if (strlen(tz) != tz_len) {
34263522
php_error_docref(NULL, E_WARNING, "Timezone must not contain null bytes");
34273523
efree(dummy_t);
3428-
return FAILURE;
3524+
return false;
34293525
}
34303526

34313527
dummy_t->z = timelib_parse_zone(&tz, &dst, dummy_t, &not_found, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper);
34323528
if (not_found) {
34333529
php_error_docref(NULL, E_WARNING, "Unknown or bad timezone (%s)", orig_tz);
34343530
efree(dummy_t);
3435-
return FAILURE;
3531+
return false;
34363532
} else {
34373533
set_timezone_from_timelib_time(tzobj, dummy_t);
34383534
timelib_free(dummy_t->tz_abbr);
34393535
efree(dummy_t);
3440-
return SUCCESS;
3536+
return true;
34413537
}
34423538
} /* }}} */
34433539

@@ -3452,7 +3548,7 @@ PHP_FUNCTION(timezone_open)
34523548
ZEND_PARSE_PARAMETERS_END();
34533549

34543550
tzobj = Z_PHPTIMEZONE_P(php_date_instantiate(date_ce_timezone, return_value));
3455-
if (FAILURE == timezone_initialize(tzobj, ZSTR_VAL(tz), ZSTR_LEN(tz))) {
3551+
if (!timezone_initialize(tzobj, ZSTR_VAL(tz), ZSTR_LEN(tz))) {
34563552
zval_ptr_dtor(return_value);
34573553
RETURN_FALSE;
34583554
}
@@ -3477,25 +3573,25 @@ PHP_METHOD(DateTimeZone, __construct)
34773573
}
34783574
/* }}} */
34793575

3480-
static zend_result php_date_timezone_initialize_from_hash(zval **return_value, php_timezone_obj **tzobj, HashTable *myht) /* {{{ */
3576+
static bool php_date_timezone_initialize_from_hash(zval **return_value, php_timezone_obj **tzobj, HashTable *myht) /* {{{ */
34813577
{
34823578
zval *z_timezone_type;
34833579

34843580
if ((z_timezone_type = zend_hash_str_find(myht, "timezone_type", sizeof("timezone_type") - 1)) == NULL) {
3485-
return FAILURE;
3581+
return false;
34863582
}
34873583

34883584
zval *z_timezone;
34893585

34903586
if ((z_timezone = zend_hash_str_find(myht, "timezone", sizeof("timezone") - 1)) == NULL) {
3491-
return FAILURE;
3587+
return false;
34923588
}
34933589

34943590
if (Z_TYPE_P(z_timezone_type) != IS_LONG) {
3495-
return FAILURE;
3591+
return false;
34963592
}
34973593
if (Z_TYPE_P(z_timezone) != IS_STRING) {
3498-
return FAILURE;
3594+
return false;
34993595
}
35003596
return timezone_initialize(*tzobj, Z_STRVAL_P(z_timezone), Z_STRLEN_P(z_timezone));
35013597
} /* }}} */
@@ -3515,7 +3611,7 @@ PHP_METHOD(DateTimeZone, __set_state)
35153611

35163612
php_date_instantiate(date_ce_timezone, return_value);
35173613
tzobj = Z_PHPTIMEZONE_P(return_value);
3518-
if (php_date_timezone_initialize_from_hash(&return_value, &tzobj, myht) == FAILURE) {
3614+
if (!php_date_timezone_initialize_from_hash(&return_value, &tzobj, myht)) {
35193615
zend_throw_error(NULL, "Timezone initialization failed");
35203616
zval_ptr_dtor(return_value);
35213617
}
@@ -3535,12 +3631,51 @@ PHP_METHOD(DateTimeZone, __wakeup)
35353631

35363632
myht = Z_OBJPROP_P(object);
35373633

3538-
if (php_date_timezone_initialize_from_hash(&return_value, &tzobj, myht) == FAILURE) {
3634+
if (!php_date_timezone_initialize_from_hash(&return_value, &tzobj, myht)) {
35393635
zend_throw_error(NULL, "Timezone initialization failed");
35403636
}
35413637
}
35423638
/* }}} */
35433639

3640+
/* {{{ */
3641+
PHP_METHOD(DateTimeZone, __serialize)
3642+
{
3643+
zval *object = ZEND_THIS;
3644+
php_timezone_obj *tzobj;
3645+
HashTable *myht;
3646+
3647+
ZEND_PARSE_PARAMETERS_NONE();
3648+
3649+
tzobj = Z_PHPTIMEZONE_P(object);
3650+
DATE_CHECK_INITIALIZED(tzobj->initialized, DateTimeZone);
3651+
3652+
array_init(return_value);
3653+
myht = Z_ARRVAL_P(return_value);
3654+
date_timezone_object_to_hash(tzobj, myht);
3655+
}
3656+
/* }}} */
3657+
3658+
/* {{{ */
3659+
PHP_METHOD(DateTimeZone, __unserialize)
3660+
{
3661+
zval *object = ZEND_THIS;
3662+
php_timezone_obj *tzobj;
3663+
zval *array;
3664+
HashTable *myht;
3665+
3666+
ZEND_PARSE_PARAMETERS_START(1, 1)
3667+
Z_PARAM_ARRAY(array)
3668+
ZEND_PARSE_PARAMETERS_END();
3669+
3670+
tzobj = Z_PHPTIMEZONE_P(object);
3671+
myht = Z_ARRVAL_P(array);
3672+
3673+
if (!php_date_timezone_initialize_from_hash(&object, &tzobj, myht)) {
3674+
zend_throw_error(NULL, "Invalid serialization data for DateTimeZone object");
3675+
}
3676+
}
3677+
/* }}} */
3678+
35443679
/* {{{ Returns the name of the timezone. */
35453680
PHP_FUNCTION(timezone_name_get)
35463681
{

ext/date/php_date.stub.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,12 +205,20 @@ public function diff(DateTimeInterface $targetObject, bool $absolute = false): D
205205

206206
/** @tentative-return-type */
207207
public function __wakeup(): void;
208+
209+
public function __serialize(): array;
210+
211+
public function __unserialize(array $data): void;
208212
}
209213

210214
class DateTime implements DateTimeInterface
211215
{
212216
public function __construct(string $datetime = "now", ?DateTimeZone $timezone = null) {}
213217

218+
public function __serialize(): array {}
219+
220+
public function __unserialize(array $data): void {}
221+
214222
/** @tentative-return-type */
215223
public function __wakeup(): void {}
216224

@@ -318,6 +326,10 @@ class DateTimeImmutable implements DateTimeInterface
318326
{
319327
public function __construct(string $datetime = "now", ?DateTimeZone $timezone = null) {}
320328

329+
public function __serialize(): array {}
330+
331+
public function __unserialize(array $data): void {}
332+
321333
/** @tentative-return-type */
322334
public function __wakeup(): void {}
323335

@@ -441,6 +453,10 @@ public static function listAbbreviations(): array {}
441453
*/
442454
public static function listIdentifiers(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode = null): array {}
443455

456+
public function __serialize(): array {}
457+
458+
public function __unserialize(array $data): void {}
459+
444460
/** @tentative-return-type */
445461
public function __wakeup(): void {}
446462

0 commit comments

Comments
 (0)