Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions ext/date/php_date.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand All @@ -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;
}
Expand Down
41 changes: 41 additions & 0 deletions ext/date/tests/date_interval_wakeup_declared_property.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
--TEST--
DateInterval::__wakeup() must not pass raw property-table zvals to zval_get_double()/zval_get_long()
--FILE--
<?php
error_reporting(E_ALL & ~E_DEPRECATED);

/* date_object_get_properties_interval() returns the object's raw property table
* when the interval is not initialized. Declared properties are IS_INDIRECT in
* that table, which the conversion helpers do not accept. */

class DeclaredInitialized extends DateInterval { public float $f = 1.5; }
class DeclaredUninitialized extends DateInterval { public float $f; }
class DeclaredCivilOrWall extends DateInterval { public int $civil_or_wall = 1; }
#[AllowDynamicProperties] class Dynamic extends DateInterval {}

foreach (['DeclaredInitialized', 'DeclaredUninitialized', 'DeclaredCivilOrWall'] as $cls) {
$o = (new ReflectionClass($cls))->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
Loading