diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 0e24e4450641..690713eeb5e5 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -4733,7 +4733,7 @@ static void php_date_interval_initialize_from_hash(php_interval_obj *intobj, con PHP_DATE_INTERVAL_READ_PROPERTY("s", s, timelib_sll, -1) { const zval *z_arg = zend_hash_str_find(myht, "f", sizeof("f") - 1); - if (z_arg) { + if (z_arg && Z_TYPE_P(z_arg) <= IS_STRING) { intobj->diff->us = zend_dval_to_lval(zval_get_double(z_arg) * 1000000.0); } } @@ -4749,7 +4749,7 @@ static void php_date_interval_initialize_from_hash(php_interval_obj *intobj, con { const zval *z_arg = zend_hash_str_find(myht, "civil_or_wall", sizeof("civil_or_wall") - 1); intobj->civil_or_wall = PHP_DATE_CIVIL; - if (z_arg) { + if (z_arg && Z_TYPE_P(z_arg) <= IS_STRING) { zend_long val = zval_get_long(z_arg); intobj->civil_or_wall = val; } diff --git a/ext/date/tests/date_interval_wakeup_declared_property.phpt b/ext/date/tests/date_interval_wakeup_declared_property.phpt new file mode 100644 index 000000000000..5478c2ef7ae8 --- /dev/null +++ b/ext/date/tests/date_interval_wakeup_declared_property.phpt @@ -0,0 +1,41 @@ +--TEST-- +DateInterval::__wakeup() must not pass raw property-table zvals to zval_get_double()/zval_get_long() +--FILE-- +newInstanceWithoutConstructor(); + $o->__wakeup(); + echo $cls, ": ok\n"; +} + +/* A dynamic property is a plain zval, so it is still read normally. */ +$o = (new ReflectionClass('Dynamic'))->newInstanceWithoutConstructor(); +$o->f = 0.25; +$o->__wakeup(); +echo "Dynamic: ", $o->f, "\n"; + +/* The normal round-trip is unaffected. */ +$i = new DateInterval('PT1S'); +$i->f = 0.5; +$restored = unserialize(serialize($i)); +echo "roundtrip f: ", $restored->f, "\n"; +echo "roundtrip s: ", $restored->s, "\n"; +?> +--EXPECT-- +DeclaredInitialized: ok +DeclaredUninitialized: ok +DeclaredCivilOrWall: ok +Dynamic: 0.25 +roundtrip f: 0.5 +roundtrip s: 1